1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * PF_INET6 socket protocol family |
4 | * Linux INET6 implementation |
5 | * |
6 | * Authors: |
7 | * Pedro Roque <roque@di.fc.ul.pt> |
8 | * |
9 | * Adapted from linux/net/ipv4/af_inet.c |
10 | * |
11 | * Fixes: |
12 | * piggy, Karl Knutson : Socket protocol table |
13 | * Hideaki YOSHIFUJI : sin6_scope_id support |
14 | * Arnaldo Melo : check proc_net_create return, cleanups |
15 | */ |
16 | |
17 | #define pr_fmt(fmt) "IPv6: " fmt |
18 | |
19 | #include <linux/module.h> |
20 | #include <linux/capability.h> |
21 | #include <linux/errno.h> |
22 | #include <linux/types.h> |
23 | #include <linux/socket.h> |
24 | #include <linux/in.h> |
25 | #include <linux/kernel.h> |
26 | #include <linux/timer.h> |
27 | #include <linux/string.h> |
28 | #include <linux/sockios.h> |
29 | #include <linux/net.h> |
30 | #include <linux/fcntl.h> |
31 | #include <linux/mm.h> |
32 | #include <linux/interrupt.h> |
33 | #include <linux/proc_fs.h> |
34 | #include <linux/stat.h> |
35 | #include <linux/init.h> |
36 | #include <linux/slab.h> |
37 | |
38 | #include <linux/inet.h> |
39 | #include <linux/netdevice.h> |
40 | #include <linux/icmpv6.h> |
41 | #include <linux/netfilter_ipv6.h> |
42 | |
43 | #include <net/ip.h> |
44 | #include <net/ipv6.h> |
45 | #include <net/udp.h> |
46 | #include <net/udplite.h> |
47 | #include <net/tcp.h> |
48 | #include <net/ping.h> |
49 | #include <net/protocol.h> |
50 | #include <net/inet_common.h> |
51 | #include <net/route.h> |
52 | #include <net/transp_v6.h> |
53 | #include <net/ip6_route.h> |
54 | #include <net/addrconf.h> |
55 | #include <net/ipv6_stubs.h> |
56 | #include <net/ndisc.h> |
57 | #ifdef CONFIG_IPV6_TUNNEL |
58 | #include <net/ip6_tunnel.h> |
59 | #endif |
60 | #include <net/calipso.h> |
61 | #include <net/seg6.h> |
62 | #include <net/rpl.h> |
63 | #include <net/compat.h> |
64 | #include <net/xfrm.h> |
65 | #include <net/ioam6.h> |
66 | #include <net/rawv6.h> |
67 | #include <net/rps.h> |
68 | |
69 | #include <linux/uaccess.h> |
70 | #include <linux/mroute6.h> |
71 | |
72 | #include "ip6_offload.h" |
73 | |
74 | MODULE_AUTHOR("Cast of dozens" ); |
75 | MODULE_DESCRIPTION("IPv6 protocol stack for Linux" ); |
76 | MODULE_LICENSE("GPL" ); |
77 | |
78 | /* The inetsw6 table contains everything that inet6_create needs to |
79 | * build a new socket. |
80 | */ |
81 | static struct list_head inetsw6[SOCK_MAX]; |
82 | static DEFINE_SPINLOCK(inetsw6_lock); |
83 | |
84 | struct ipv6_params ipv6_defaults = { |
85 | .disable_ipv6 = 0, |
86 | .autoconf = 1, |
87 | }; |
88 | |
89 | static int disable_ipv6_mod; |
90 | |
91 | module_param_named(disable, disable_ipv6_mod, int, 0444); |
92 | MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional" ); |
93 | |
94 | module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); |
95 | MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces" ); |
96 | |
97 | module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); |
98 | MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces" ); |
99 | |
100 | bool ipv6_mod_enabled(void) |
101 | { |
102 | return disable_ipv6_mod == 0; |
103 | } |
104 | EXPORT_SYMBOL_GPL(ipv6_mod_enabled); |
105 | |
106 | static struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) |
107 | { |
108 | const int offset = sk->sk_prot->ipv6_pinfo_offset; |
109 | |
110 | return (struct ipv6_pinfo *)(((u8 *)sk) + offset); |
111 | } |
112 | |
113 | void inet6_sock_destruct(struct sock *sk) |
114 | { |
115 | inet6_cleanup_sock(sk); |
116 | inet_sock_destruct(sk); |
117 | } |
118 | EXPORT_SYMBOL_GPL(inet6_sock_destruct); |
119 | |
120 | static int inet6_create(struct net *net, struct socket *sock, int protocol, |
121 | int kern) |
122 | { |
123 | struct inet_sock *inet; |
124 | struct ipv6_pinfo *np; |
125 | struct sock *sk; |
126 | struct inet_protosw *answer; |
127 | struct proto *answer_prot; |
128 | unsigned char answer_flags; |
129 | int try_loading_module = 0; |
130 | int err; |
131 | |
132 | if (protocol < 0 || protocol >= IPPROTO_MAX) |
133 | return -EINVAL; |
134 | |
135 | /* Look for the requested type/protocol pair. */ |
136 | lookup_protocol: |
137 | err = -ESOCKTNOSUPPORT; |
138 | rcu_read_lock(); |
139 | list_for_each_entry_rcu(answer, &inetsw6[sock->type], list) { |
140 | |
141 | err = 0; |
142 | /* Check the non-wild match. */ |
143 | if (protocol == answer->protocol) { |
144 | if (protocol != IPPROTO_IP) |
145 | break; |
146 | } else { |
147 | /* Check for the two wild cases. */ |
148 | if (IPPROTO_IP == protocol) { |
149 | protocol = answer->protocol; |
150 | break; |
151 | } |
152 | if (IPPROTO_IP == answer->protocol) |
153 | break; |
154 | } |
155 | err = -EPROTONOSUPPORT; |
156 | } |
157 | |
158 | if (err) { |
159 | if (try_loading_module < 2) { |
160 | rcu_read_unlock(); |
161 | /* |
162 | * Be more specific, e.g. net-pf-10-proto-132-type-1 |
163 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM) |
164 | */ |
165 | if (++try_loading_module == 1) |
166 | request_module("net-pf-%d-proto-%d-type-%d" , |
167 | PF_INET6, protocol, sock->type); |
168 | /* |
169 | * Fall back to generic, e.g. net-pf-10-proto-132 |
170 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP) |
171 | */ |
172 | else |
173 | request_module("net-pf-%d-proto-%d" , |
174 | PF_INET6, protocol); |
175 | goto lookup_protocol; |
176 | } else |
177 | goto out_rcu_unlock; |
178 | } |
179 | |
180 | err = -EPERM; |
181 | if (sock->type == SOCK_RAW && !kern && |
182 | !ns_capable(ns: net->user_ns, CAP_NET_RAW)) |
183 | goto out_rcu_unlock; |
184 | |
185 | sock->ops = answer->ops; |
186 | answer_prot = answer->prot; |
187 | answer_flags = answer->flags; |
188 | rcu_read_unlock(); |
189 | |
190 | WARN_ON(!answer_prot->slab); |
191 | |
192 | err = -ENOBUFS; |
193 | sk = sk_alloc(net, PF_INET6, GFP_KERNEL, prot: answer_prot, kern); |
194 | if (!sk) |
195 | goto out; |
196 | |
197 | sock_init_data(sock, sk); |
198 | |
199 | err = 0; |
200 | if (INET_PROTOSW_REUSE & answer_flags) |
201 | sk->sk_reuse = SK_CAN_REUSE; |
202 | |
203 | if (INET_PROTOSW_ICSK & answer_flags) |
204 | inet_init_csk_locks(sk); |
205 | |
206 | inet = inet_sk(sk); |
207 | inet_assign_bit(IS_ICSK, sk, INET_PROTOSW_ICSK & answer_flags); |
208 | |
209 | if (SOCK_RAW == sock->type) { |
210 | inet->inet_num = protocol; |
211 | if (IPPROTO_RAW == protocol) |
212 | inet_set_bit(HDRINCL, sk); |
213 | } |
214 | |
215 | sk->sk_destruct = inet6_sock_destruct; |
216 | sk->sk_family = PF_INET6; |
217 | sk->sk_protocol = protocol; |
218 | |
219 | sk->sk_backlog_rcv = answer->prot->backlog_rcv; |
220 | |
221 | inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk); |
222 | np->hop_limit = -1; |
223 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; |
224 | inet6_set_bit(MC6_LOOP, sk); |
225 | inet6_set_bit(MC6_ALL, sk); |
226 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
227 | inet6_assign_bit(REPFLOW, sk, net->ipv6.sysctl.flowlabel_reflect & |
228 | FLOWLABEL_REFLECT_ESTABLISHED); |
229 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; |
230 | sk->sk_txrehash = READ_ONCE(net->core.sysctl_txrehash); |
231 | |
232 | /* Init the ipv4 part of the socket since we can have sockets |
233 | * using v6 API for ipv4. |
234 | */ |
235 | inet->uc_ttl = -1; |
236 | |
237 | inet_set_bit(MC_LOOP, sk); |
238 | inet->mc_ttl = 1; |
239 | inet->mc_index = 0; |
240 | RCU_INIT_POINTER(inet->mc_list, NULL); |
241 | inet->rcv_tos = 0; |
242 | |
243 | if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc)) |
244 | inet->pmtudisc = IP_PMTUDISC_DONT; |
245 | else |
246 | inet->pmtudisc = IP_PMTUDISC_WANT; |
247 | |
248 | if (inet->inet_num) { |
249 | /* It assumes that any protocol which allows |
250 | * the user to assign a number at socket |
251 | * creation time automatically shares. |
252 | */ |
253 | inet->inet_sport = htons(inet->inet_num); |
254 | err = sk->sk_prot->hash(sk); |
255 | if (err) { |
256 | sk_common_release(sk); |
257 | goto out; |
258 | } |
259 | } |
260 | if (sk->sk_prot->init) { |
261 | err = sk->sk_prot->init(sk); |
262 | if (err) { |
263 | sk_common_release(sk); |
264 | goto out; |
265 | } |
266 | } |
267 | |
268 | if (!kern) { |
269 | err = BPF_CGROUP_RUN_PROG_INET_SOCK(sk); |
270 | if (err) { |
271 | sk_common_release(sk); |
272 | goto out; |
273 | } |
274 | } |
275 | out: |
276 | return err; |
277 | out_rcu_unlock: |
278 | rcu_read_unlock(); |
279 | goto out; |
280 | } |
281 | |
282 | static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, |
283 | u32 flags) |
284 | { |
285 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)uaddr; |
286 | struct inet_sock *inet = inet_sk(sk); |
287 | struct ipv6_pinfo *np = inet6_sk(sk: sk); |
288 | struct net *net = sock_net(sk); |
289 | __be32 v4addr = 0; |
290 | unsigned short snum; |
291 | bool saved_ipv6only; |
292 | int addr_type = 0; |
293 | int err = 0; |
294 | |
295 | if (addr->sin6_family != AF_INET6) |
296 | return -EAFNOSUPPORT; |
297 | |
298 | addr_type = ipv6_addr_type(addr: &addr->sin6_addr); |
299 | if ((addr_type & IPV6_ADDR_MULTICAST) && sk->sk_type == SOCK_STREAM) |
300 | return -EINVAL; |
301 | |
302 | snum = ntohs(addr->sin6_port); |
303 | if (!(flags & BIND_NO_CAP_NET_BIND_SERVICE) && |
304 | snum && inet_port_requires_bind_service(net, port: snum) && |
305 | !ns_capable(ns: net->user_ns, CAP_NET_BIND_SERVICE)) |
306 | return -EACCES; |
307 | |
308 | if (flags & BIND_WITH_LOCK) |
309 | lock_sock(sk); |
310 | |
311 | /* Check these errors (active socket, double bind). */ |
312 | if (sk->sk_state != TCP_CLOSE || inet->inet_num) { |
313 | err = -EINVAL; |
314 | goto out; |
315 | } |
316 | |
317 | /* Check if the address belongs to the host. */ |
318 | if (addr_type == IPV6_ADDR_MAPPED) { |
319 | struct net_device *dev = NULL; |
320 | int chk_addr_ret; |
321 | |
322 | /* Binding to v4-mapped address on a v6-only socket |
323 | * makes no sense |
324 | */ |
325 | if (ipv6_only_sock(sk)) { |
326 | err = -EINVAL; |
327 | goto out; |
328 | } |
329 | |
330 | rcu_read_lock(); |
331 | if (sk->sk_bound_dev_if) { |
332 | dev = dev_get_by_index_rcu(net, ifindex: sk->sk_bound_dev_if); |
333 | if (!dev) { |
334 | err = -ENODEV; |
335 | goto out_unlock; |
336 | } |
337 | } |
338 | |
339 | /* Reproduce AF_INET checks to make the bindings consistent */ |
340 | v4addr = addr->sin6_addr.s6_addr32[3]; |
341 | chk_addr_ret = inet_addr_type_dev_table(net, dev, addr: v4addr); |
342 | rcu_read_unlock(); |
343 | |
344 | if (!inet_addr_valid_or_nonlocal(net, inet, addr: v4addr, |
345 | addr_type: chk_addr_ret)) { |
346 | err = -EADDRNOTAVAIL; |
347 | goto out; |
348 | } |
349 | } else { |
350 | if (addr_type != IPV6_ADDR_ANY) { |
351 | struct net_device *dev = NULL; |
352 | |
353 | rcu_read_lock(); |
354 | if (__ipv6_addr_needs_scope_id(type: addr_type)) { |
355 | if (addr_len >= sizeof(struct sockaddr_in6) && |
356 | addr->sin6_scope_id) { |
357 | /* Override any existing binding, if another one |
358 | * is supplied by user. |
359 | */ |
360 | sk->sk_bound_dev_if = addr->sin6_scope_id; |
361 | } |
362 | |
363 | /* Binding to link-local address requires an interface */ |
364 | if (!sk->sk_bound_dev_if) { |
365 | err = -EINVAL; |
366 | goto out_unlock; |
367 | } |
368 | } |
369 | |
370 | if (sk->sk_bound_dev_if) { |
371 | dev = dev_get_by_index_rcu(net, ifindex: sk->sk_bound_dev_if); |
372 | if (!dev) { |
373 | err = -ENODEV; |
374 | goto out_unlock; |
375 | } |
376 | } |
377 | |
378 | /* ipv4 addr of the socket is invalid. Only the |
379 | * unspecified and mapped address have a v4 equivalent. |
380 | */ |
381 | v4addr = LOOPBACK4_IPV6; |
382 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { |
383 | if (!ipv6_can_nonlocal_bind(net, inet) && |
384 | !ipv6_chk_addr(net, addr: &addr->sin6_addr, |
385 | dev, strict: 0)) { |
386 | err = -EADDRNOTAVAIL; |
387 | goto out_unlock; |
388 | } |
389 | } |
390 | rcu_read_unlock(); |
391 | } |
392 | } |
393 | |
394 | inet->inet_rcv_saddr = v4addr; |
395 | inet->inet_saddr = v4addr; |
396 | |
397 | sk->sk_v6_rcv_saddr = addr->sin6_addr; |
398 | |
399 | if (!(addr_type & IPV6_ADDR_MULTICAST)) |
400 | np->saddr = addr->sin6_addr; |
401 | |
402 | saved_ipv6only = sk->sk_ipv6only; |
403 | if (addr_type != IPV6_ADDR_ANY && addr_type != IPV6_ADDR_MAPPED) |
404 | sk->sk_ipv6only = 1; |
405 | |
406 | /* Make sure we are allowed to bind here. */ |
407 | if (snum || !(inet_test_bit(BIND_ADDRESS_NO_PORT, sk) || |
408 | (flags & BIND_FORCE_ADDRESS_NO_PORT))) { |
409 | err = sk->sk_prot->get_port(sk, snum); |
410 | if (err) { |
411 | sk->sk_ipv6only = saved_ipv6only; |
412 | inet_reset_saddr(sk); |
413 | goto out; |
414 | } |
415 | if (!(flags & BIND_FROM_BPF)) { |
416 | err = BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk); |
417 | if (err) { |
418 | sk->sk_ipv6only = saved_ipv6only; |
419 | inet_reset_saddr(sk); |
420 | if (sk->sk_prot->put_port) |
421 | sk->sk_prot->put_port(sk); |
422 | goto out; |
423 | } |
424 | } |
425 | } |
426 | |
427 | if (addr_type != IPV6_ADDR_ANY) |
428 | sk->sk_userlocks |= SOCK_BINDADDR_LOCK; |
429 | if (snum) |
430 | sk->sk_userlocks |= SOCK_BINDPORT_LOCK; |
431 | inet->inet_sport = htons(inet->inet_num); |
432 | inet->inet_dport = 0; |
433 | inet->inet_daddr = 0; |
434 | out: |
435 | if (flags & BIND_WITH_LOCK) |
436 | release_sock(sk); |
437 | return err; |
438 | out_unlock: |
439 | rcu_read_unlock(); |
440 | goto out; |
441 | } |
442 | |
443 | int inet6_bind_sk(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
444 | { |
445 | u32 flags = BIND_WITH_LOCK; |
446 | const struct proto *prot; |
447 | int err = 0; |
448 | |
449 | /* IPV6_ADDRFORM can change sk->sk_prot under us. */ |
450 | prot = READ_ONCE(sk->sk_prot); |
451 | /* If the socket has its own bind function then use it. */ |
452 | if (prot->bind) |
453 | return prot->bind(sk, uaddr, addr_len); |
454 | |
455 | if (addr_len < SIN6_LEN_RFC2133) |
456 | return -EINVAL; |
457 | |
458 | /* BPF prog is run before any checks are done so that if the prog |
459 | * changes context in a wrong way it will be caught. |
460 | */ |
461 | err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, &addr_len, |
462 | CGROUP_INET6_BIND, &flags); |
463 | if (err) |
464 | return err; |
465 | |
466 | return __inet6_bind(sk, uaddr, addr_len, flags); |
467 | } |
468 | |
469 | /* bind for INET6 API */ |
470 | int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
471 | { |
472 | return inet6_bind_sk(sk: sock->sk, uaddr, addr_len); |
473 | } |
474 | EXPORT_SYMBOL(inet6_bind); |
475 | |
476 | int inet6_release(struct socket *sock) |
477 | { |
478 | struct sock *sk = sock->sk; |
479 | |
480 | if (!sk) |
481 | return -EINVAL; |
482 | |
483 | /* Free mc lists */ |
484 | ipv6_sock_mc_close(sk); |
485 | |
486 | /* Free ac lists */ |
487 | ipv6_sock_ac_close(sk); |
488 | |
489 | return inet_release(sock); |
490 | } |
491 | EXPORT_SYMBOL(inet6_release); |
492 | |
493 | void inet6_cleanup_sock(struct sock *sk) |
494 | { |
495 | struct ipv6_pinfo *np = inet6_sk(sk: sk); |
496 | struct sk_buff *skb; |
497 | struct ipv6_txoptions *opt; |
498 | |
499 | /* Release rx options */ |
500 | |
501 | skb = xchg(&np->pktoptions, NULL); |
502 | kfree_skb(skb); |
503 | |
504 | skb = xchg(&np->rxpmtu, NULL); |
505 | kfree_skb(skb); |
506 | |
507 | /* Free flowlabels */ |
508 | fl6_free_socklist(sk); |
509 | |
510 | /* Free tx options */ |
511 | |
512 | opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); |
513 | if (opt) { |
514 | atomic_sub(i: opt->tot_len, v: &sk->sk_omem_alloc); |
515 | txopt_put(opt); |
516 | } |
517 | } |
518 | EXPORT_SYMBOL_GPL(inet6_cleanup_sock); |
519 | |
520 | /* |
521 | * This does both peername and sockname. |
522 | */ |
523 | int inet6_getname(struct socket *sock, struct sockaddr *uaddr, |
524 | int peer) |
525 | { |
526 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr; |
527 | int sin_addr_len = sizeof(*sin); |
528 | struct sock *sk = sock->sk; |
529 | struct inet_sock *inet = inet_sk(sk); |
530 | struct ipv6_pinfo *np = inet6_sk(sk: sk); |
531 | |
532 | sin->sin6_family = AF_INET6; |
533 | sin->sin6_flowinfo = 0; |
534 | sin->sin6_scope_id = 0; |
535 | lock_sock(sk); |
536 | if (peer) { |
537 | if (!inet->inet_dport || |
538 | (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && |
539 | peer == 1)) { |
540 | release_sock(sk); |
541 | return -ENOTCONN; |
542 | } |
543 | sin->sin6_port = inet->inet_dport; |
544 | sin->sin6_addr = sk->sk_v6_daddr; |
545 | if (inet6_test_bit(SNDFLOW, sk)) |
546 | sin->sin6_flowinfo = np->flow_label; |
547 | BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, |
548 | CGROUP_INET6_GETPEERNAME); |
549 | } else { |
550 | if (ipv6_addr_any(a: &sk->sk_v6_rcv_saddr)) |
551 | sin->sin6_addr = np->saddr; |
552 | else |
553 | sin->sin6_addr = sk->sk_v6_rcv_saddr; |
554 | sin->sin6_port = inet->inet_sport; |
555 | BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, |
556 | CGROUP_INET6_GETSOCKNAME); |
557 | } |
558 | sin->sin6_scope_id = ipv6_iface_scope_id(addr: &sin->sin6_addr, |
559 | iface: sk->sk_bound_dev_if); |
560 | release_sock(sk); |
561 | return sin_addr_len; |
562 | } |
563 | EXPORT_SYMBOL(inet6_getname); |
564 | |
565 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
566 | { |
567 | void __user *argp = (void __user *)arg; |
568 | struct sock *sk = sock->sk; |
569 | struct net *net = sock_net(sk); |
570 | const struct proto *prot; |
571 | |
572 | switch (cmd) { |
573 | case SIOCADDRT: |
574 | case SIOCDELRT: { |
575 | struct in6_rtmsg rtmsg; |
576 | |
577 | if (copy_from_user(to: &rtmsg, from: argp, n: sizeof(rtmsg))) |
578 | return -EFAULT; |
579 | return ipv6_route_ioctl(net, cmd, rtmsg: &rtmsg); |
580 | } |
581 | case SIOCSIFADDR: |
582 | return addrconf_add_ifaddr(net, arg: argp); |
583 | case SIOCDIFADDR: |
584 | return addrconf_del_ifaddr(net, arg: argp); |
585 | case SIOCSIFDSTADDR: |
586 | return addrconf_set_dstaddr(net, arg: argp); |
587 | default: |
588 | /* IPV6_ADDRFORM can change sk->sk_prot under us. */ |
589 | prot = READ_ONCE(sk->sk_prot); |
590 | if (!prot->ioctl) |
591 | return -ENOIOCTLCMD; |
592 | return sk_ioctl(sk, cmd, arg: (void __user *)arg); |
593 | } |
594 | /*NOTREACHED*/ |
595 | return 0; |
596 | } |
597 | EXPORT_SYMBOL(inet6_ioctl); |
598 | |
599 | #ifdef CONFIG_COMPAT |
600 | struct compat_in6_rtmsg { |
601 | struct in6_addr rtmsg_dst; |
602 | struct in6_addr rtmsg_src; |
603 | struct in6_addr rtmsg_gateway; |
604 | u32 rtmsg_type; |
605 | u16 rtmsg_dst_len; |
606 | u16 rtmsg_src_len; |
607 | u32 rtmsg_metric; |
608 | u32 rtmsg_info; |
609 | u32 rtmsg_flags; |
610 | s32 rtmsg_ifindex; |
611 | }; |
612 | |
613 | static int inet6_compat_routing_ioctl(struct sock *sk, unsigned int cmd, |
614 | struct compat_in6_rtmsg __user *ur) |
615 | { |
616 | struct in6_rtmsg rt; |
617 | |
618 | if (copy_from_user(to: &rt.rtmsg_dst, from: &ur->rtmsg_dst, |
619 | n: 3 * sizeof(struct in6_addr)) || |
620 | get_user(rt.rtmsg_type, &ur->rtmsg_type) || |
621 | get_user(rt.rtmsg_dst_len, &ur->rtmsg_dst_len) || |
622 | get_user(rt.rtmsg_src_len, &ur->rtmsg_src_len) || |
623 | get_user(rt.rtmsg_metric, &ur->rtmsg_metric) || |
624 | get_user(rt.rtmsg_info, &ur->rtmsg_info) || |
625 | get_user(rt.rtmsg_flags, &ur->rtmsg_flags) || |
626 | get_user(rt.rtmsg_ifindex, &ur->rtmsg_ifindex)) |
627 | return -EFAULT; |
628 | |
629 | |
630 | return ipv6_route_ioctl(net: sock_net(sk), cmd, rtmsg: &rt); |
631 | } |
632 | |
633 | int inet6_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
634 | { |
635 | void __user *argp = compat_ptr(uptr: arg); |
636 | struct sock *sk = sock->sk; |
637 | |
638 | switch (cmd) { |
639 | case SIOCADDRT: |
640 | case SIOCDELRT: |
641 | return inet6_compat_routing_ioctl(sk, cmd, ur: argp); |
642 | default: |
643 | return -ENOIOCTLCMD; |
644 | } |
645 | } |
646 | EXPORT_SYMBOL_GPL(inet6_compat_ioctl); |
647 | #endif /* CONFIG_COMPAT */ |
648 | |
649 | INDIRECT_CALLABLE_DECLARE(int udpv6_sendmsg(struct sock *, struct msghdr *, |
650 | size_t)); |
651 | int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) |
652 | { |
653 | struct sock *sk = sock->sk; |
654 | const struct proto *prot; |
655 | |
656 | if (unlikely(inet_send_prepare(sk))) |
657 | return -EAGAIN; |
658 | |
659 | /* IPV6_ADDRFORM can change sk->sk_prot under us. */ |
660 | prot = READ_ONCE(sk->sk_prot); |
661 | return INDIRECT_CALL_2(prot->sendmsg, tcp_sendmsg, udpv6_sendmsg, |
662 | sk, msg, size); |
663 | } |
664 | |
665 | INDIRECT_CALLABLE_DECLARE(int udpv6_recvmsg(struct sock *, struct msghdr *, |
666 | size_t, int, int *)); |
667 | int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, |
668 | int flags) |
669 | { |
670 | struct sock *sk = sock->sk; |
671 | const struct proto *prot; |
672 | int addr_len = 0; |
673 | int err; |
674 | |
675 | if (likely(!(flags & MSG_ERRQUEUE))) |
676 | sock_rps_record_flow(sk); |
677 | |
678 | /* IPV6_ADDRFORM can change sk->sk_prot under us. */ |
679 | prot = READ_ONCE(sk->sk_prot); |
680 | err = INDIRECT_CALL_2(prot->recvmsg, tcp_recvmsg, udpv6_recvmsg, |
681 | sk, msg, size, flags, &addr_len); |
682 | if (err >= 0) |
683 | msg->msg_namelen = addr_len; |
684 | return err; |
685 | } |
686 | |
687 | const struct proto_ops inet6_stream_ops = { |
688 | .family = PF_INET6, |
689 | .owner = THIS_MODULE, |
690 | .release = inet6_release, |
691 | .bind = inet6_bind, |
692 | .connect = inet_stream_connect, /* ok */ |
693 | .socketpair = sock_no_socketpair, /* a do nothing */ |
694 | .accept = inet_accept, /* ok */ |
695 | .getname = inet6_getname, |
696 | .poll = tcp_poll, /* ok */ |
697 | .ioctl = inet6_ioctl, /* must change */ |
698 | .gettstamp = sock_gettstamp, |
699 | .listen = inet_listen, /* ok */ |
700 | .shutdown = inet_shutdown, /* ok */ |
701 | .setsockopt = sock_common_setsockopt, /* ok */ |
702 | .getsockopt = sock_common_getsockopt, /* ok */ |
703 | .sendmsg = inet6_sendmsg, /* retpoline's sake */ |
704 | .recvmsg = inet6_recvmsg, /* retpoline's sake */ |
705 | #ifdef CONFIG_MMU |
706 | .mmap = tcp_mmap, |
707 | #endif |
708 | .splice_eof = inet_splice_eof, |
709 | .sendmsg_locked = tcp_sendmsg_locked, |
710 | .splice_read = tcp_splice_read, |
711 | .read_sock = tcp_read_sock, |
712 | .read_skb = tcp_read_skb, |
713 | .peek_len = tcp_peek_len, |
714 | #ifdef CONFIG_COMPAT |
715 | .compat_ioctl = inet6_compat_ioctl, |
716 | #endif |
717 | .set_rcvlowat = tcp_set_rcvlowat, |
718 | }; |
719 | |
720 | const struct proto_ops inet6_dgram_ops = { |
721 | .family = PF_INET6, |
722 | .owner = THIS_MODULE, |
723 | .release = inet6_release, |
724 | .bind = inet6_bind, |
725 | .connect = inet_dgram_connect, /* ok */ |
726 | .socketpair = sock_no_socketpair, /* a do nothing */ |
727 | .accept = sock_no_accept, /* a do nothing */ |
728 | .getname = inet6_getname, |
729 | .poll = udp_poll, /* ok */ |
730 | .ioctl = inet6_ioctl, /* must change */ |
731 | .gettstamp = sock_gettstamp, |
732 | .listen = sock_no_listen, /* ok */ |
733 | .shutdown = inet_shutdown, /* ok */ |
734 | .setsockopt = sock_common_setsockopt, /* ok */ |
735 | .getsockopt = sock_common_getsockopt, /* ok */ |
736 | .sendmsg = inet6_sendmsg, /* retpoline's sake */ |
737 | .recvmsg = inet6_recvmsg, /* retpoline's sake */ |
738 | .read_skb = udp_read_skb, |
739 | .mmap = sock_no_mmap, |
740 | .set_peek_off = udp_set_peek_off, |
741 | #ifdef CONFIG_COMPAT |
742 | .compat_ioctl = inet6_compat_ioctl, |
743 | #endif |
744 | }; |
745 | |
746 | static const struct net_proto_family inet6_family_ops = { |
747 | .family = PF_INET6, |
748 | .create = inet6_create, |
749 | .owner = THIS_MODULE, |
750 | }; |
751 | |
752 | int inet6_register_protosw(struct inet_protosw *p) |
753 | { |
754 | struct list_head *lh; |
755 | struct inet_protosw *answer; |
756 | struct list_head *last_perm; |
757 | int protocol = p->protocol; |
758 | int ret; |
759 | |
760 | spin_lock_bh(lock: &inetsw6_lock); |
761 | |
762 | ret = -EINVAL; |
763 | if (p->type >= SOCK_MAX) |
764 | goto out_illegal; |
765 | |
766 | /* If we are trying to override a permanent protocol, bail. */ |
767 | answer = NULL; |
768 | ret = -EPERM; |
769 | last_perm = &inetsw6[p->type]; |
770 | list_for_each(lh, &inetsw6[p->type]) { |
771 | answer = list_entry(lh, struct inet_protosw, list); |
772 | |
773 | /* Check only the non-wild match. */ |
774 | if (INET_PROTOSW_PERMANENT & answer->flags) { |
775 | if (protocol == answer->protocol) |
776 | break; |
777 | last_perm = lh; |
778 | } |
779 | |
780 | answer = NULL; |
781 | } |
782 | if (answer) |
783 | goto out_permanent; |
784 | |
785 | /* Add the new entry after the last permanent entry if any, so that |
786 | * the new entry does not override a permanent entry when matched with |
787 | * a wild-card protocol. But it is allowed to override any existing |
788 | * non-permanent entry. This means that when we remove this entry, the |
789 | * system automatically returns to the old behavior. |
790 | */ |
791 | list_add_rcu(new: &p->list, head: last_perm); |
792 | ret = 0; |
793 | out: |
794 | spin_unlock_bh(lock: &inetsw6_lock); |
795 | return ret; |
796 | |
797 | out_permanent: |
798 | pr_err("Attempt to override permanent protocol %d\n" , protocol); |
799 | goto out; |
800 | |
801 | out_illegal: |
802 | pr_err("Ignoring attempt to register invalid socket type %d\n" , |
803 | p->type); |
804 | goto out; |
805 | } |
806 | EXPORT_SYMBOL(inet6_register_protosw); |
807 | |
808 | void |
809 | inet6_unregister_protosw(struct inet_protosw *p) |
810 | { |
811 | if (INET_PROTOSW_PERMANENT & p->flags) { |
812 | pr_err("Attempt to unregister permanent protocol %d\n" , |
813 | p->protocol); |
814 | } else { |
815 | spin_lock_bh(lock: &inetsw6_lock); |
816 | list_del_rcu(entry: &p->list); |
817 | spin_unlock_bh(lock: &inetsw6_lock); |
818 | |
819 | synchronize_net(); |
820 | } |
821 | } |
822 | EXPORT_SYMBOL(inet6_unregister_protosw); |
823 | |
824 | int (struct sock *sk) |
825 | { |
826 | struct ipv6_pinfo *np = inet6_sk(sk: sk); |
827 | struct dst_entry *dst; |
828 | |
829 | dst = __sk_dst_check(sk, cookie: np->dst_cookie); |
830 | |
831 | if (!dst) { |
832 | struct inet_sock *inet = inet_sk(sk); |
833 | struct in6_addr *final_p, final; |
834 | struct flowi6 fl6; |
835 | |
836 | memset(&fl6, 0, sizeof(fl6)); |
837 | fl6.flowi6_proto = sk->sk_protocol; |
838 | fl6.daddr = sk->sk_v6_daddr; |
839 | fl6.saddr = np->saddr; |
840 | fl6.flowlabel = np->flow_label; |
841 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
842 | fl6.flowi6_mark = sk->sk_mark; |
843 | fl6.fl6_dport = inet->inet_dport; |
844 | fl6.fl6_sport = inet->inet_sport; |
845 | fl6.flowi6_uid = sk->sk_uid; |
846 | security_sk_classify_flow(sk, flic: flowi6_to_flowi_common(fl6: &fl6)); |
847 | |
848 | rcu_read_lock(); |
849 | final_p = fl6_update_dst(fl6: &fl6, rcu_dereference(np->opt), |
850 | orig: &final); |
851 | rcu_read_unlock(); |
852 | |
853 | dst = ip6_dst_lookup_flow(net: sock_net(sk), sk, fl6: &fl6, final_dst: final_p); |
854 | if (IS_ERR(ptr: dst)) { |
855 | sk->sk_route_caps = 0; |
856 | WRITE_ONCE(sk->sk_err_soft, -PTR_ERR(dst)); |
857 | return PTR_ERR(ptr: dst); |
858 | } |
859 | |
860 | ip6_dst_store(sk, dst, NULL, NULL); |
861 | } |
862 | |
863 | return 0; |
864 | } |
865 | EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header); |
866 | |
867 | bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb, |
868 | const struct inet6_skb_parm *opt) |
869 | { |
870 | const struct ipv6_pinfo *np = inet6_sk(sk: sk); |
871 | |
872 | if (np->rxopt.all) { |
873 | if (((opt->flags & IP6SKB_HOPBYHOP) && |
874 | (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) || |
875 | (ip6_flowinfo(hdr: (struct ipv6hdr *) skb_network_header(skb)) && |
876 | np->rxopt.bits.rxflow) || |
877 | (opt->srcrt && (np->rxopt.bits.srcrt || |
878 | np->rxopt.bits.osrcrt)) || |
879 | ((opt->dst1 || opt->dst0) && |
880 | (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) |
881 | return true; |
882 | } |
883 | return false; |
884 | } |
885 | EXPORT_SYMBOL_GPL(ipv6_opt_accepted); |
886 | |
887 | static struct packet_type ipv6_packet_type __read_mostly = { |
888 | .type = cpu_to_be16(ETH_P_IPV6), |
889 | .func = ipv6_rcv, |
890 | .list_func = ipv6_list_rcv, |
891 | }; |
892 | |
893 | static int __init ipv6_packet_init(void) |
894 | { |
895 | dev_add_pack(pt: &ipv6_packet_type); |
896 | return 0; |
897 | } |
898 | |
899 | static void ipv6_packet_cleanup(void) |
900 | { |
901 | dev_remove_pack(pt: &ipv6_packet_type); |
902 | } |
903 | |
904 | static int __net_init ipv6_init_mibs(struct net *net) |
905 | { |
906 | int i; |
907 | |
908 | net->mib.udp_stats_in6 = alloc_percpu(struct udp_mib); |
909 | if (!net->mib.udp_stats_in6) |
910 | return -ENOMEM; |
911 | net->mib.udplite_stats_in6 = alloc_percpu(struct udp_mib); |
912 | if (!net->mib.udplite_stats_in6) |
913 | goto err_udplite_mib; |
914 | net->mib.ipv6_statistics = alloc_percpu(struct ipstats_mib); |
915 | if (!net->mib.ipv6_statistics) |
916 | goto err_ip_mib; |
917 | |
918 | for_each_possible_cpu(i) { |
919 | struct ipstats_mib *af_inet6_stats; |
920 | af_inet6_stats = per_cpu_ptr(net->mib.ipv6_statistics, i); |
921 | u64_stats_init(syncp: &af_inet6_stats->syncp); |
922 | } |
923 | |
924 | |
925 | net->mib.icmpv6_statistics = alloc_percpu(struct icmpv6_mib); |
926 | if (!net->mib.icmpv6_statistics) |
927 | goto err_icmp_mib; |
928 | net->mib.icmpv6msg_statistics = kzalloc(size: sizeof(struct icmpv6msg_mib), |
929 | GFP_KERNEL); |
930 | if (!net->mib.icmpv6msg_statistics) |
931 | goto err_icmpmsg_mib; |
932 | return 0; |
933 | |
934 | err_icmpmsg_mib: |
935 | free_percpu(pdata: net->mib.icmpv6_statistics); |
936 | err_icmp_mib: |
937 | free_percpu(pdata: net->mib.ipv6_statistics); |
938 | err_ip_mib: |
939 | free_percpu(pdata: net->mib.udplite_stats_in6); |
940 | err_udplite_mib: |
941 | free_percpu(pdata: net->mib.udp_stats_in6); |
942 | return -ENOMEM; |
943 | } |
944 | |
945 | static void ipv6_cleanup_mibs(struct net *net) |
946 | { |
947 | free_percpu(pdata: net->mib.udp_stats_in6); |
948 | free_percpu(pdata: net->mib.udplite_stats_in6); |
949 | free_percpu(pdata: net->mib.ipv6_statistics); |
950 | free_percpu(pdata: net->mib.icmpv6_statistics); |
951 | kfree(objp: net->mib.icmpv6msg_statistics); |
952 | } |
953 | |
954 | static int __net_init inet6_net_init(struct net *net) |
955 | { |
956 | int err = 0; |
957 | |
958 | net->ipv6.sysctl.bindv6only = 0; |
959 | net->ipv6.sysctl.icmpv6_time = 1*HZ; |
960 | net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; |
961 | net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; |
962 | net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0; |
963 | net->ipv6.sysctl.icmpv6_error_anycast_as_unicast = 0; |
964 | |
965 | /* By default, rate limit error messages. |
966 | * Except for pmtu discovery, it would break it. |
967 | * proc_do_large_bitmap needs pointer to the bitmap. |
968 | */ |
969 | bitmap_set(map: net->ipv6.sysctl.icmpv6_ratemask, start: 0, ICMPV6_ERRMSG_MAX + 1); |
970 | bitmap_clear(map: net->ipv6.sysctl.icmpv6_ratemask, ICMPV6_PKT_TOOBIG, nbits: 1); |
971 | net->ipv6.sysctl.icmpv6_ratemask_ptr = net->ipv6.sysctl.icmpv6_ratemask; |
972 | |
973 | net->ipv6.sysctl.flowlabel_consistency = 1; |
974 | net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS; |
975 | net->ipv6.sysctl.idgen_retries = 3; |
976 | net->ipv6.sysctl.idgen_delay = 1 * HZ; |
977 | net->ipv6.sysctl.flowlabel_state_ranges = 0; |
978 | net->ipv6.sysctl.max_dst_opts_cnt = IP6_DEFAULT_MAX_DST_OPTS_CNT; |
979 | net->ipv6.sysctl.max_hbh_opts_cnt = IP6_DEFAULT_MAX_HBH_OPTS_CNT; |
980 | net->ipv6.sysctl.max_dst_opts_len = IP6_DEFAULT_MAX_DST_OPTS_LEN; |
981 | net->ipv6.sysctl.max_hbh_opts_len = IP6_DEFAULT_MAX_HBH_OPTS_LEN; |
982 | net->ipv6.sysctl.fib_notify_on_flag_change = 0; |
983 | atomic_set(v: &net->ipv6.fib6_sernum, i: 1); |
984 | |
985 | net->ipv6.sysctl.ioam6_id = IOAM6_DEFAULT_ID; |
986 | net->ipv6.sysctl.ioam6_id_wide = IOAM6_DEFAULT_ID_WIDE; |
987 | |
988 | err = ipv6_init_mibs(net); |
989 | if (err) |
990 | return err; |
991 | #ifdef CONFIG_PROC_FS |
992 | err = udp6_proc_init(net); |
993 | if (err) |
994 | goto out; |
995 | err = tcp6_proc_init(net); |
996 | if (err) |
997 | goto proc_tcp6_fail; |
998 | err = ac6_proc_init(net); |
999 | if (err) |
1000 | goto proc_ac6_fail; |
1001 | #endif |
1002 | return err; |
1003 | |
1004 | #ifdef CONFIG_PROC_FS |
1005 | proc_ac6_fail: |
1006 | tcp6_proc_exit(net); |
1007 | proc_tcp6_fail: |
1008 | udp6_proc_exit(net); |
1009 | out: |
1010 | ipv6_cleanup_mibs(net); |
1011 | return err; |
1012 | #endif |
1013 | } |
1014 | |
1015 | static void __net_exit inet6_net_exit(struct net *net) |
1016 | { |
1017 | #ifdef CONFIG_PROC_FS |
1018 | udp6_proc_exit(net); |
1019 | tcp6_proc_exit(net); |
1020 | ac6_proc_exit(net); |
1021 | #endif |
1022 | ipv6_cleanup_mibs(net); |
1023 | } |
1024 | |
1025 | static struct pernet_operations inet6_net_ops = { |
1026 | .init = inet6_net_init, |
1027 | .exit = inet6_net_exit, |
1028 | }; |
1029 | |
1030 | static int ipv6_route_input(struct sk_buff *skb) |
1031 | { |
1032 | ip6_route_input(skb); |
1033 | return skb_dst(skb)->error; |
1034 | } |
1035 | |
1036 | static const struct ipv6_stub ipv6_stub_impl = { |
1037 | .ipv6_sock_mc_join = ipv6_sock_mc_join, |
1038 | .ipv6_sock_mc_drop = ipv6_sock_mc_drop, |
1039 | .ipv6_dst_lookup_flow = ip6_dst_lookup_flow, |
1040 | .ipv6_route_input = ipv6_route_input, |
1041 | .fib6_get_table = fib6_get_table, |
1042 | .fib6_table_lookup = fib6_table_lookup, |
1043 | .fib6_lookup = fib6_lookup, |
1044 | .fib6_select_path = fib6_select_path, |
1045 | .ip6_mtu_from_fib6 = ip6_mtu_from_fib6, |
1046 | .fib6_nh_init = fib6_nh_init, |
1047 | .fib6_nh_release = fib6_nh_release, |
1048 | .fib6_nh_release_dsts = fib6_nh_release_dsts, |
1049 | .fib6_update_sernum = fib6_update_sernum_stub, |
1050 | .fib6_rt_update = fib6_rt_update, |
1051 | .ip6_del_rt = ip6_del_rt, |
1052 | .udpv6_encap_enable = udpv6_encap_enable, |
1053 | .ndisc_send_na = ndisc_send_na, |
1054 | #if IS_ENABLED(CONFIG_XFRM) |
1055 | .xfrm6_local_rxpmtu = xfrm6_local_rxpmtu, |
1056 | .xfrm6_udp_encap_rcv = xfrm6_udp_encap_rcv, |
1057 | .xfrm6_gro_udp_encap_rcv = xfrm6_gro_udp_encap_rcv, |
1058 | .xfrm6_rcv_encap = xfrm6_rcv_encap, |
1059 | #endif |
1060 | .nd_tbl = &nd_tbl, |
1061 | .ipv6_fragment = ip6_fragment, |
1062 | .ipv6_dev_find = ipv6_dev_find, |
1063 | }; |
1064 | |
1065 | static const struct ipv6_bpf_stub ipv6_bpf_stub_impl = { |
1066 | .inet6_bind = __inet6_bind, |
1067 | .udp6_lib_lookup = __udp6_lib_lookup, |
1068 | .ipv6_setsockopt = do_ipv6_setsockopt, |
1069 | .ipv6_getsockopt = do_ipv6_getsockopt, |
1070 | .ipv6_dev_get_saddr = ipv6_dev_get_saddr, |
1071 | }; |
1072 | |
1073 | static int __init inet6_init(void) |
1074 | { |
1075 | struct list_head *r; |
1076 | int err = 0; |
1077 | |
1078 | sock_skb_cb_check_size(sizeof(struct inet6_skb_parm)); |
1079 | |
1080 | /* Register the socket-side information for inet6_create. */ |
1081 | for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) |
1082 | INIT_LIST_HEAD(list: r); |
1083 | |
1084 | raw_hashinfo_init(hashinfo: &raw_v6_hashinfo); |
1085 | |
1086 | if (disable_ipv6_mod) { |
1087 | pr_info("Loaded, but administratively disabled, reboot required to enable\n" ); |
1088 | goto out; |
1089 | } |
1090 | |
1091 | err = proto_register(prot: &tcpv6_prot, alloc_slab: 1); |
1092 | if (err) |
1093 | goto out; |
1094 | |
1095 | err = proto_register(prot: &udpv6_prot, alloc_slab: 1); |
1096 | if (err) |
1097 | goto out_unregister_tcp_proto; |
1098 | |
1099 | err = proto_register(prot: &udplitev6_prot, alloc_slab: 1); |
1100 | if (err) |
1101 | goto out_unregister_udp_proto; |
1102 | |
1103 | err = proto_register(prot: &rawv6_prot, alloc_slab: 1); |
1104 | if (err) |
1105 | goto out_unregister_udplite_proto; |
1106 | |
1107 | err = proto_register(prot: &pingv6_prot, alloc_slab: 1); |
1108 | if (err) |
1109 | goto out_unregister_raw_proto; |
1110 | |
1111 | /* We MUST register RAW sockets before we create the ICMP6, |
1112 | * IGMP6, or NDISC control sockets. |
1113 | */ |
1114 | err = rawv6_init(); |
1115 | if (err) |
1116 | goto out_unregister_ping_proto; |
1117 | |
1118 | /* Register the family here so that the init calls below will |
1119 | * be able to create sockets. (?? is this dangerous ??) |
1120 | */ |
1121 | err = sock_register(fam: &inet6_family_ops); |
1122 | if (err) |
1123 | goto out_sock_register_fail; |
1124 | |
1125 | /* |
1126 | * ipngwg API draft makes clear that the correct semantics |
1127 | * for TCP and UDP is to consider one TCP and UDP instance |
1128 | * in a host available by both INET and INET6 APIs and |
1129 | * able to communicate via both network protocols. |
1130 | */ |
1131 | |
1132 | err = register_pernet_subsys(&inet6_net_ops); |
1133 | if (err) |
1134 | goto register_pernet_fail; |
1135 | err = ip6_mr_init(); |
1136 | if (err) |
1137 | goto ipmr_fail; |
1138 | err = icmpv6_init(); |
1139 | if (err) |
1140 | goto icmp_fail; |
1141 | err = ndisc_init(); |
1142 | if (err) |
1143 | goto ndisc_fail; |
1144 | err = igmp6_init(); |
1145 | if (err) |
1146 | goto igmp_fail; |
1147 | |
1148 | err = ipv6_netfilter_init(); |
1149 | if (err) |
1150 | goto netfilter_fail; |
1151 | /* Create /proc/foo6 entries. */ |
1152 | #ifdef CONFIG_PROC_FS |
1153 | err = -ENOMEM; |
1154 | if (raw6_proc_init()) |
1155 | goto proc_raw6_fail; |
1156 | if (udplite6_proc_init()) |
1157 | goto proc_udplite6_fail; |
1158 | if (ipv6_misc_proc_init()) |
1159 | goto proc_misc6_fail; |
1160 | if (if6_proc_init()) |
1161 | goto proc_if6_fail; |
1162 | #endif |
1163 | err = ip6_route_init(); |
1164 | if (err) |
1165 | goto ip6_route_fail; |
1166 | err = ndisc_late_init(); |
1167 | if (err) |
1168 | goto ndisc_late_fail; |
1169 | err = ip6_flowlabel_init(); |
1170 | if (err) |
1171 | goto ip6_flowlabel_fail; |
1172 | err = ipv6_anycast_init(); |
1173 | if (err) |
1174 | goto ipv6_anycast_fail; |
1175 | err = addrconf_init(); |
1176 | if (err) |
1177 | goto addrconf_fail; |
1178 | |
1179 | /* Init v6 extension headers. */ |
1180 | err = ipv6_exthdrs_init(); |
1181 | if (err) |
1182 | goto ipv6_exthdrs_fail; |
1183 | |
1184 | err = ipv6_frag_init(); |
1185 | if (err) |
1186 | goto ipv6_frag_fail; |
1187 | |
1188 | /* Init v6 transport protocols. */ |
1189 | err = udpv6_init(); |
1190 | if (err) |
1191 | goto udpv6_fail; |
1192 | |
1193 | err = udplitev6_init(); |
1194 | if (err) |
1195 | goto udplitev6_fail; |
1196 | |
1197 | err = udpv6_offload_init(); |
1198 | if (err) |
1199 | goto udpv6_offload_fail; |
1200 | |
1201 | err = tcpv6_init(); |
1202 | if (err) |
1203 | goto tcpv6_fail; |
1204 | |
1205 | err = ipv6_packet_init(); |
1206 | if (err) |
1207 | goto ipv6_packet_fail; |
1208 | |
1209 | err = pingv6_init(); |
1210 | if (err) |
1211 | goto pingv6_fail; |
1212 | |
1213 | err = calipso_init(); |
1214 | if (err) |
1215 | goto calipso_fail; |
1216 | |
1217 | err = seg6_init(); |
1218 | if (err) |
1219 | goto seg6_fail; |
1220 | |
1221 | err = rpl_init(); |
1222 | if (err) |
1223 | goto rpl_fail; |
1224 | |
1225 | err = ioam6_init(); |
1226 | if (err) |
1227 | goto ioam6_fail; |
1228 | |
1229 | err = igmp6_late_init(); |
1230 | if (err) |
1231 | goto igmp6_late_err; |
1232 | |
1233 | #ifdef CONFIG_SYSCTL |
1234 | err = ipv6_sysctl_register(); |
1235 | if (err) |
1236 | goto sysctl_fail; |
1237 | #endif |
1238 | |
1239 | /* ensure that ipv6 stubs are visible only after ipv6 is ready */ |
1240 | wmb(); |
1241 | ipv6_stub = &ipv6_stub_impl; |
1242 | ipv6_bpf_stub = &ipv6_bpf_stub_impl; |
1243 | out: |
1244 | return err; |
1245 | |
1246 | #ifdef CONFIG_SYSCTL |
1247 | sysctl_fail: |
1248 | igmp6_late_cleanup(); |
1249 | #endif |
1250 | igmp6_late_err: |
1251 | ioam6_exit(); |
1252 | ioam6_fail: |
1253 | rpl_exit(); |
1254 | rpl_fail: |
1255 | seg6_exit(); |
1256 | seg6_fail: |
1257 | calipso_exit(); |
1258 | calipso_fail: |
1259 | pingv6_exit(); |
1260 | pingv6_fail: |
1261 | ipv6_packet_cleanup(); |
1262 | ipv6_packet_fail: |
1263 | tcpv6_exit(); |
1264 | tcpv6_fail: |
1265 | udpv6_offload_exit(); |
1266 | udpv6_offload_fail: |
1267 | udplitev6_exit(); |
1268 | udplitev6_fail: |
1269 | udpv6_exit(); |
1270 | udpv6_fail: |
1271 | ipv6_frag_exit(); |
1272 | ipv6_frag_fail: |
1273 | ipv6_exthdrs_exit(); |
1274 | ipv6_exthdrs_fail: |
1275 | addrconf_cleanup(); |
1276 | addrconf_fail: |
1277 | ipv6_anycast_cleanup(); |
1278 | ipv6_anycast_fail: |
1279 | ip6_flowlabel_cleanup(); |
1280 | ip6_flowlabel_fail: |
1281 | ndisc_late_cleanup(); |
1282 | ndisc_late_fail: |
1283 | ip6_route_cleanup(); |
1284 | ip6_route_fail: |
1285 | #ifdef CONFIG_PROC_FS |
1286 | if6_proc_exit(); |
1287 | proc_if6_fail: |
1288 | ipv6_misc_proc_exit(); |
1289 | proc_misc6_fail: |
1290 | udplite6_proc_exit(); |
1291 | proc_udplite6_fail: |
1292 | raw6_proc_exit(); |
1293 | proc_raw6_fail: |
1294 | #endif |
1295 | ipv6_netfilter_fini(); |
1296 | netfilter_fail: |
1297 | igmp6_cleanup(); |
1298 | igmp_fail: |
1299 | ndisc_cleanup(); |
1300 | ndisc_fail: |
1301 | icmpv6_cleanup(); |
1302 | icmp_fail: |
1303 | ip6_mr_cleanup(); |
1304 | ipmr_fail: |
1305 | unregister_pernet_subsys(&inet6_net_ops); |
1306 | register_pernet_fail: |
1307 | sock_unregister(PF_INET6); |
1308 | rtnl_unregister_all(PF_INET6); |
1309 | out_sock_register_fail: |
1310 | rawv6_exit(); |
1311 | out_unregister_ping_proto: |
1312 | proto_unregister(prot: &pingv6_prot); |
1313 | out_unregister_raw_proto: |
1314 | proto_unregister(prot: &rawv6_prot); |
1315 | out_unregister_udplite_proto: |
1316 | proto_unregister(prot: &udplitev6_prot); |
1317 | out_unregister_udp_proto: |
1318 | proto_unregister(prot: &udpv6_prot); |
1319 | out_unregister_tcp_proto: |
1320 | proto_unregister(prot: &tcpv6_prot); |
1321 | goto out; |
1322 | } |
1323 | module_init(inet6_init); |
1324 | |
1325 | MODULE_ALIAS_NETPROTO(PF_INET6); |
1326 | |