Branch data Line data Source code
1 : : /*
2 : : * TCP over IPv6
3 : : * Linux INET6 implementation
4 : : *
5 : : * Authors:
6 : : * Pedro Roque <roque@di.fc.ul.pt>
7 : : *
8 : : * Based on:
9 : : * linux/net/ipv4/tcp.c
10 : : * linux/net/ipv4/tcp_input.c
11 : : * linux/net/ipv4/tcp_output.c
12 : : *
13 : : * Fixes:
14 : : * Hideaki YOSHIFUJI : sin6_scope_id support
15 : : * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which
16 : : * Alexey Kuznetsov allow both IPv4 and IPv6 sockets to bind
17 : : * a single port at the same time.
18 : : * YOSHIFUJI Hideaki @USAGI: convert /proc/net/tcp6 to seq_file.
19 : : *
20 : : * This program is free software; you can redistribute it and/or
21 : : * modify it under the terms of the GNU General Public License
22 : : * as published by the Free Software Foundation; either version
23 : : * 2 of the License, or (at your option) any later version.
24 : : */
25 : :
26 : : #include <linux/bottom_half.h>
27 : : #include <linux/module.h>
28 : : #include <linux/errno.h>
29 : : #include <linux/types.h>
30 : : #include <linux/socket.h>
31 : : #include <linux/sockios.h>
32 : : #include <linux/net.h>
33 : : #include <linux/jiffies.h>
34 : : #include <linux/in.h>
35 : : #include <linux/in6.h>
36 : : #include <linux/netdevice.h>
37 : : #include <linux/init.h>
38 : : #include <linux/jhash.h>
39 : : #include <linux/ipsec.h>
40 : : #include <linux/times.h>
41 : : #include <linux/slab.h>
42 : :
43 : : #include <linux/ipv6.h>
44 : : #include <linux/icmpv6.h>
45 : : #include <linux/random.h>
46 : :
47 : : #include <net/tcp.h>
48 : : #include <net/ndisc.h>
49 : : #include <net/inet6_hashtables.h>
50 : : #include <net/inet6_connection_sock.h>
51 : : #include <net/ipv6.h>
52 : : #include <net/transp_v6.h>
53 : : #include <net/addrconf.h>
54 : : #include <net/ip6_route.h>
55 : : #include <net/ip6_checksum.h>
56 : : #include <net/inet_ecn.h>
57 : : #include <net/protocol.h>
58 : : #include <net/xfrm.h>
59 : : #include <net/snmp.h>
60 : : #include <net/dsfield.h>
61 : : #include <net/timewait_sock.h>
62 : : #include <net/netdma.h>
63 : : #include <net/inet_common.h>
64 : : #include <net/secure_seq.h>
65 : : #include <net/tcp_memcontrol.h>
66 : : #include <net/busy_poll.h>
67 : :
68 : : #include <asm/uaccess.h>
69 : :
70 : : #include <linux/proc_fs.h>
71 : : #include <linux/seq_file.h>
72 : :
73 : : #include <linux/crypto.h>
74 : : #include <linux/scatterlist.h>
75 : :
76 : : static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
77 : : static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
78 : : struct request_sock *req);
79 : :
80 : : static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
81 : :
82 : : static const struct inet_connection_sock_af_ops ipv6_mapped;
83 : : static const struct inet_connection_sock_af_ops ipv6_specific;
84 : : #ifdef CONFIG_TCP_MD5SIG
85 : : static const struct tcp_sock_af_ops tcp_sock_ipv6_specific;
86 : : static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
87 : : #else
88 : : static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
89 : : const struct in6_addr *addr)
90 : : {
91 : : return NULL;
92 : : }
93 : : #endif
94 : :
95 : 0 : static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
96 : : {
97 : : struct dst_entry *dst = skb_dst(skb);
98 : : const struct rt6_info *rt = (const struct rt6_info *)dst;
99 : :
100 : : dst_hold(dst);
101 : 0 : sk->sk_rx_dst = dst;
102 : 0 : inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
103 [ # # ]: 0 : if (rt->rt6i_node)
104 : 0 : inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
105 : 0 : }
106 : :
107 : 0 : static void tcp_v6_hash(struct sock *sk)
108 : : {
109 [ # # ]: 0 : if (sk->sk_state != TCP_CLOSE) {
110 [ # # ]: 0 : if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) {
111 : 0 : tcp_prot.hash(sk);
112 : 0 : return;
113 : : }
114 : 0 : local_bh_disable();
115 : 0 : __inet6_hash(sk, NULL);
116 : 0 : local_bh_enable();
117 : : }
118 : : }
119 : :
120 : 0 : static __u32 tcp_v6_init_sequence(const struct sk_buff *skb)
121 : : {
122 : 0 : return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
123 : 0 : ipv6_hdr(skb)->saddr.s6_addr32,
124 : : tcp_hdr(skb)->dest,
125 : : tcp_hdr(skb)->source);
126 : : }
127 : :
128 : 0 : static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
129 : : int addr_len)
130 : : {
131 : : struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
132 : : struct inet_sock *inet = inet_sk(sk);
133 : : struct inet_connection_sock *icsk = inet_csk(sk);
134 : : struct ipv6_pinfo *np = inet6_sk(sk);
135 : : struct tcp_sock *tp = tcp_sk(sk);
136 : : struct in6_addr *saddr = NULL, *final_p, final;
137 : : struct rt6_info *rt;
138 : : struct flowi6 fl6;
139 : : struct dst_entry *dst;
140 : : int addr_type;
141 : : int err;
142 : :
143 [ # # ]: 0 : if (addr_len < SIN6_LEN_RFC2133)
144 : : return -EINVAL;
145 : :
146 [ # # ]: 0 : if (usin->sin6_family != AF_INET6)
147 : : return -EAFNOSUPPORT;
148 : :
149 : 0 : memset(&fl6, 0, sizeof(fl6));
150 : :
151 [ # # ]: 0 : if (np->sndflow) {
152 : 0 : fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
153 : 0 : IP6_ECN_flow_init(fl6.flowlabel);
154 [ # # ]: 0 : if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
155 : : struct ip6_flowlabel *flowlabel;
156 : 0 : flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
157 [ # # ]: 0 : if (flowlabel == NULL)
158 : : return -EINVAL;
159 : : fl6_sock_release(flowlabel);
160 : : }
161 : : }
162 : :
163 : : /*
164 : : * connect() to INADDR_ANY means loopback (BSD'ism).
165 : : */
166 : :
167 [ # # ]: 0 : if(ipv6_addr_any(&usin->sin6_addr))
168 : 0 : usin->sin6_addr.s6_addr[15] = 0x1;
169 : :
170 : 0 : addr_type = ipv6_addr_type(&usin->sin6_addr);
171 : :
172 [ # # ]: 0 : if(addr_type & IPV6_ADDR_MULTICAST)
173 : : return -ENETUNREACH;
174 : :
175 [ # # ]: 0 : if (addr_type&IPV6_ADDR_LINKLOCAL) {
176 [ # # ][ # # ]: 0 : if (addr_len >= sizeof(struct sockaddr_in6) &&
177 : 0 : usin->sin6_scope_id) {
178 : : /* If interface is set while binding, indices
179 : : * must coincide.
180 : : */
181 [ # # ][ # # ]: 0 : if (sk->sk_bound_dev_if &&
182 : 0 : sk->sk_bound_dev_if != usin->sin6_scope_id)
183 : : return -EINVAL;
184 : :
185 : 0 : sk->sk_bound_dev_if = usin->sin6_scope_id;
186 : : }
187 : :
188 : : /* Connect to link-local address requires an interface */
189 [ # # ]: 0 : if (!sk->sk_bound_dev_if)
190 : : return -EINVAL;
191 : : }
192 : :
193 [ # # ][ # # ]: 0 : if (tp->rx_opt.ts_recent_stamp &&
194 : : !ipv6_addr_equal(&sk->sk_v6_daddr, &usin->sin6_addr)) {
195 : 0 : tp->rx_opt.ts_recent = 0;
196 : 0 : tp->rx_opt.ts_recent_stamp = 0;
197 : 0 : tp->write_seq = 0;
198 : : }
199 : :
200 : 0 : sk->sk_v6_daddr = usin->sin6_addr;
201 : 0 : np->flow_label = fl6.flowlabel;
202 : :
203 : : /*
204 : : * TCP over IPv4
205 : : */
206 : :
207 [ # # ]: 0 : if (addr_type == IPV6_ADDR_MAPPED) {
208 : 0 : u32 exthdrlen = icsk->icsk_ext_hdr_len;
209 : : struct sockaddr_in sin;
210 : :
211 [ # # ][ # # ]: 0 : SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
212 : :
213 [ # # ]: 0 : if (__ipv6_only_sock(sk))
214 : 0 : return -ENETUNREACH;
215 : :
216 : 0 : sin.sin_family = AF_INET;
217 : 0 : sin.sin_port = usin->sin6_port;
218 : 0 : sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
219 : :
220 : 0 : icsk->icsk_af_ops = &ipv6_mapped;
221 : 0 : sk->sk_backlog_rcv = tcp_v4_do_rcv;
222 : : #ifdef CONFIG_TCP_MD5SIG
223 : : tp->af_specific = &tcp_sock_ipv6_mapped_specific;
224 : : #endif
225 : :
226 : 0 : err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
227 : :
228 [ # # ]: 0 : if (err) {
229 : 0 : icsk->icsk_ext_hdr_len = exthdrlen;
230 : 0 : icsk->icsk_af_ops = &ipv6_specific;
231 : 0 : sk->sk_backlog_rcv = tcp_v6_do_rcv;
232 : : #ifdef CONFIG_TCP_MD5SIG
233 : : tp->af_specific = &tcp_sock_ipv6_specific;
234 : : #endif
235 : 0 : goto failure;
236 : : } else {
237 : 0 : ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
238 : 0 : ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
239 : : &sk->sk_v6_rcv_saddr);
240 : : }
241 : :
242 : 0 : return err;
243 : : }
244 : :
245 [ # # ]: 0 : if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr))
246 : 0 : saddr = &sk->sk_v6_rcv_saddr;
247 : :
248 : 0 : fl6.flowi6_proto = IPPROTO_TCP;
249 : 0 : fl6.daddr = sk->sk_v6_daddr;
250 [ # # ]: 0 : fl6.saddr = saddr ? *saddr : np->saddr;
251 : 0 : fl6.flowi6_oif = sk->sk_bound_dev_if;
252 : 0 : fl6.flowi6_mark = sk->sk_mark;
253 : 0 : fl6.fl6_dport = usin->sin6_port;
254 : 0 : fl6.fl6_sport = inet->inet_sport;
255 : :
256 : 0 : final_p = fl6_update_dst(&fl6, np->opt, &final);
257 : :
258 : 0 : security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
259 : :
260 : 0 : dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
261 [ # # ]: 0 : if (IS_ERR(dst)) {
262 : : err = PTR_ERR(dst);
263 : 0 : goto failure;
264 : : }
265 : :
266 [ # # ]: 0 : if (saddr == NULL) {
267 : : saddr = &fl6.saddr;
268 : 0 : sk->sk_v6_rcv_saddr = *saddr;
269 : : }
270 : :
271 : : /* set the source address */
272 : 0 : np->saddr = *saddr;
273 : 0 : inet->inet_rcv_saddr = LOOPBACK4_IPV6;
274 : :
275 : 0 : sk->sk_gso_type = SKB_GSO_TCPV6;
276 : : __ip6_dst_store(sk, dst, NULL, NULL);
277 : :
278 : : rt = (struct rt6_info *) dst;
279 [ # # ][ # # ]: 0 : if (tcp_death_row.sysctl_tw_recycle &&
280 [ # # ]: 0 : !tp->rx_opt.ts_recent_stamp &&
281 : : ipv6_addr_equal(&rt->rt6i_dst.addr, &sk->sk_v6_daddr))
282 : 0 : tcp_fetch_timewait_stamp(sk, dst);
283 : :
284 : 0 : icsk->icsk_ext_hdr_len = 0;
285 [ # # ]: 0 : if (np->opt)
286 : 0 : icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
287 : 0 : np->opt->opt_nflen);
288 : :
289 : 0 : tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
290 : :
291 : 0 : inet->inet_dport = usin->sin6_port;
292 : :
293 : 0 : tcp_set_state(sk, TCP_SYN_SENT);
294 : 0 : err = inet6_hash_connect(&tcp_death_row, sk);
295 [ # # ]: 0 : if (err)
296 : : goto late_failure;
297 : :
298 [ # # ][ # # ]: 0 : if (!tp->write_seq && likely(!tp->repair))
299 : 0 : tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
300 : 0 : sk->sk_v6_daddr.s6_addr32,
301 : : inet->inet_sport,
302 : : inet->inet_dport);
303 : :
304 : 0 : err = tcp_connect(sk);
305 [ # # ]: 0 : if (err)
306 : : goto late_failure;
307 : :
308 : : return 0;
309 : :
310 : : late_failure:
311 : 0 : tcp_set_state(sk, TCP_CLOSE);
312 : : __sk_dst_reset(sk);
313 : : failure:
314 : 0 : inet->inet_dport = 0;
315 : 0 : sk->sk_route_caps = 0;
316 : 0 : return err;
317 : : }
318 : :
319 : 0 : static void tcp_v6_mtu_reduced(struct sock *sk)
320 : : {
321 : : struct dst_entry *dst;
322 : :
323 [ # # ]: 0 : if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
324 : : return;
325 : :
326 : 0 : dst = inet6_csk_update_pmtu(sk, tcp_sk(sk)->mtu_info);
327 [ # # ]: 0 : if (!dst)
328 : : return;
329 : :
330 [ # # ]: 0 : if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
331 : 0 : tcp_sync_mss(sk, dst_mtu(dst));
332 : 0 : tcp_simple_retransmit(sk);
333 : : }
334 : : }
335 : :
336 : 0 : static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
337 : : u8 type, u8 code, int offset, __be32 info)
338 : : {
339 : 0 : const struct ipv6hdr *hdr = (const struct ipv6hdr*)skb->data;
340 : 0 : const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
341 : : struct ipv6_pinfo *np;
342 : : struct sock *sk;
343 : : int err;
344 : : struct tcp_sock *tp;
345 : : __u32 seq;
346 : 0 : struct net *net = dev_net(skb->dev);
347 : :
348 : 0 : sk = inet6_lookup(net, &tcp_hashinfo, &hdr->daddr,
349 : 0 : th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
350 : :
351 [ # # ]: 0 : if (sk == NULL) {
352 [ # # ]: 0 : ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
353 : : ICMP6_MIB_INERRORS);
354 : 0 : return;
355 : : }
356 : :
357 [ # # ]: 0 : if (sk->sk_state == TCP_TIME_WAIT) {
358 : 0 : inet_twsk_put(inet_twsk(sk));
359 : 0 : return;
360 : : }
361 : :
362 : : bh_lock_sock(sk);
363 [ # # ][ # # ]: 0 : if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG)
364 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
365 : :
366 [ # # ]: 0 : if (sk->sk_state == TCP_CLOSE)
367 : : goto out;
368 : :
369 [ # # ]: 0 : if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
370 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
371 : : goto out;
372 : : }
373 : :
374 : : tp = tcp_sk(sk);
375 [ # # ]: 0 : seq = ntohl(th->seq);
376 [ # # ][ # # ]: 0 : if (sk->sk_state != TCP_LISTEN &&
377 : 0 : !between(seq, tp->snd_una, tp->snd_nxt)) {
378 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
379 : : goto out;
380 : : }
381 : :
382 : : np = inet6_sk(sk);
383 : :
384 [ # # ]: 0 : if (type == NDISC_REDIRECT) {
385 : 0 : struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
386 : :
387 [ # # ]: 0 : if (dst)
388 : 0 : dst->ops->redirect(dst, sk, skb);
389 : : goto out;
390 : : }
391 : :
392 [ # # ]: 0 : if (type == ICMPV6_PKT_TOOBIG) {
393 : : /* We are not interested in TCP_LISTEN and open_requests
394 : : * (SYN-ACKs send out by Linux are always <576bytes so
395 : : * they should go through unfragmented).
396 : : */
397 [ # # ]: 0 : if (sk->sk_state == TCP_LISTEN)
398 : : goto out;
399 : :
400 [ # # ]: 0 : tp->mtu_info = ntohl(info);
401 [ # # ]: 0 : if (!sock_owned_by_user(sk))
402 : 0 : tcp_v6_mtu_reduced(sk);
403 [ # # ]: 0 : else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED,
404 : : &tp->tsq_flags))
405 : : sock_hold(sk);
406 : : goto out;
407 : : }
408 : :
409 : 0 : icmpv6_err_convert(type, code, &err);
410 : :
411 : : /* Might be for an request_sock */
412 [ # # # ]: 0 : switch (sk->sk_state) {
413 : : struct request_sock *req, **prev;
414 : : case TCP_LISTEN:
415 [ # # ]: 0 : if (sock_owned_by_user(sk))
416 : : goto out;
417 : :
418 : 0 : req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr,
419 : : &hdr->saddr, inet6_iif(skb));
420 [ # # ]: 0 : if (!req)
421 : : goto out;
422 : :
423 : : /* ICMPs are not backlogged, hence we cannot get
424 : : * an established socket here.
425 : : */
426 [ # # ]: 0 : WARN_ON(req->sk != NULL);
427 : :
428 [ # # ]: 0 : if (seq != tcp_rsk(req)->snt_isn) {
429 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
430 : : goto out;
431 : : }
432 : :
433 : 0 : inet_csk_reqsk_queue_drop(sk, req, prev);
434 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
435 : : goto out;
436 : :
437 : : case TCP_SYN_SENT:
438 : : case TCP_SYN_RECV: /* Cannot happen.
439 : : It can, it SYNs are crossed. --ANK */
440 [ # # ]: 0 : if (!sock_owned_by_user(sk)) {
441 : 0 : sk->sk_err = err;
442 : 0 : sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */
443 : :
444 : 0 : tcp_done(sk);
445 : : } else
446 : 0 : sk->sk_err_soft = err;
447 : : goto out;
448 : : }
449 : :
450 [ # # ][ # # ]: 0 : if (!sock_owned_by_user(sk) && np->recverr) {
451 : 0 : sk->sk_err = err;
452 : 0 : sk->sk_error_report(sk);
453 : : } else
454 : 0 : sk->sk_err_soft = err;
455 : :
456 : : out:
457 : : bh_unlock_sock(sk);
458 : : sock_put(sk);
459 : : }
460 : :
461 : :
462 : 0 : static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
463 : : struct flowi6 *fl6,
464 : : struct request_sock *req,
465 : : u16 queue_mapping)
466 : : {
467 : : struct inet_request_sock *ireq = inet_rsk(req);
468 : : struct ipv6_pinfo *np = inet6_sk(sk);
469 : : struct sk_buff * skb;
470 : : int err = -ENOMEM;
471 : :
472 : : /* First, grab a route. */
473 [ # # ][ # # ]: 0 : if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
474 : : goto done;
475 : :
476 : 0 : skb = tcp_make_synack(sk, dst, req, NULL);
477 : :
478 [ # # ]: 0 : if (skb) {
479 : 0 : __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr,
480 : 0 : &ireq->ir_v6_rmt_addr);
481 : :
482 : 0 : fl6->daddr = ireq->ir_v6_rmt_addr;
483 : : skb_set_queue_mapping(skb, queue_mapping);
484 : 0 : err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
485 [ # # ]: 0 : err = net_xmit_eval(err);
486 : : }
487 : :
488 : : done:
489 : 0 : return err;
490 : : }
491 : :
492 : 0 : static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req)
493 : : {
494 : : struct flowi6 fl6;
495 : : int res;
496 : :
497 : 0 : res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0);
498 [ # # ]: 0 : if (!res)
499 : 0 : TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
500 : 0 : return res;
501 : : }
502 : :
503 : 0 : static void tcp_v6_reqsk_destructor(struct request_sock *req)
504 : : {
505 : 0 : kfree_skb(inet_rsk(req)->pktopts);
506 : 0 : }
507 : :
508 : : #ifdef CONFIG_TCP_MD5SIG
509 : : static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
510 : : const struct in6_addr *addr)
511 : : {
512 : : return tcp_md5_do_lookup(sk, (union tcp_md5_addr *)addr, AF_INET6);
513 : : }
514 : :
515 : : static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk,
516 : : struct sock *addr_sk)
517 : : {
518 : : return tcp_v6_md5_do_lookup(sk, &addr_sk->sk_v6_daddr);
519 : : }
520 : :
521 : : static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
522 : : struct request_sock *req)
523 : : {
524 : : return tcp_v6_md5_do_lookup(sk, &inet_rsk(req)->ir_v6_rmt_addr);
525 : : }
526 : :
527 : : static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
528 : : int optlen)
529 : : {
530 : : struct tcp_md5sig cmd;
531 : : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr;
532 : :
533 : : if (optlen < sizeof(cmd))
534 : : return -EINVAL;
535 : :
536 : : if (copy_from_user(&cmd, optval, sizeof(cmd)))
537 : : return -EFAULT;
538 : :
539 : : if (sin6->sin6_family != AF_INET6)
540 : : return -EINVAL;
541 : :
542 : : if (!cmd.tcpm_keylen) {
543 : : if (ipv6_addr_v4mapped(&sin6->sin6_addr))
544 : : return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3],
545 : : AF_INET);
546 : : return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr,
547 : : AF_INET6);
548 : : }
549 : :
550 : : if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
551 : : return -EINVAL;
552 : :
553 : : if (ipv6_addr_v4mapped(&sin6->sin6_addr))
554 : : return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3],
555 : : AF_INET, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
556 : :
557 : : return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr,
558 : : AF_INET6, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
559 : : }
560 : :
561 : : static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
562 : : const struct in6_addr *daddr,
563 : : const struct in6_addr *saddr, int nbytes)
564 : : {
565 : : struct tcp6_pseudohdr *bp;
566 : : struct scatterlist sg;
567 : :
568 : : bp = &hp->md5_blk.ip6;
569 : : /* 1. TCP pseudo-header (RFC2460) */
570 : : bp->saddr = *saddr;
571 : : bp->daddr = *daddr;
572 : : bp->protocol = cpu_to_be32(IPPROTO_TCP);
573 : : bp->len = cpu_to_be32(nbytes);
574 : :
575 : : sg_init_one(&sg, bp, sizeof(*bp));
576 : : return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp));
577 : : }
578 : :
579 : : static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
580 : : const struct in6_addr *daddr, struct in6_addr *saddr,
581 : : const struct tcphdr *th)
582 : : {
583 : : struct tcp_md5sig_pool *hp;
584 : : struct hash_desc *desc;
585 : :
586 : : hp = tcp_get_md5sig_pool();
587 : : if (!hp)
588 : : goto clear_hash_noput;
589 : : desc = &hp->md5_desc;
590 : :
591 : : if (crypto_hash_init(desc))
592 : : goto clear_hash;
593 : : if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2))
594 : : goto clear_hash;
595 : : if (tcp_md5_hash_header(hp, th))
596 : : goto clear_hash;
597 : : if (tcp_md5_hash_key(hp, key))
598 : : goto clear_hash;
599 : : if (crypto_hash_final(desc, md5_hash))
600 : : goto clear_hash;
601 : :
602 : : tcp_put_md5sig_pool();
603 : : return 0;
604 : :
605 : : clear_hash:
606 : : tcp_put_md5sig_pool();
607 : : clear_hash_noput:
608 : : memset(md5_hash, 0, 16);
609 : : return 1;
610 : : }
611 : :
612 : : static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
613 : : const struct sock *sk,
614 : : const struct request_sock *req,
615 : : const struct sk_buff *skb)
616 : : {
617 : : const struct in6_addr *saddr, *daddr;
618 : : struct tcp_md5sig_pool *hp;
619 : : struct hash_desc *desc;
620 : : const struct tcphdr *th = tcp_hdr(skb);
621 : :
622 : : if (sk) {
623 : : saddr = &inet6_sk(sk)->saddr;
624 : : daddr = &sk->sk_v6_daddr;
625 : : } else if (req) {
626 : : saddr = &inet_rsk(req)->ir_v6_loc_addr;
627 : : daddr = &inet_rsk(req)->ir_v6_rmt_addr;
628 : : } else {
629 : : const struct ipv6hdr *ip6h = ipv6_hdr(skb);
630 : : saddr = &ip6h->saddr;
631 : : daddr = &ip6h->daddr;
632 : : }
633 : :
634 : : hp = tcp_get_md5sig_pool();
635 : : if (!hp)
636 : : goto clear_hash_noput;
637 : : desc = &hp->md5_desc;
638 : :
639 : : if (crypto_hash_init(desc))
640 : : goto clear_hash;
641 : :
642 : : if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, skb->len))
643 : : goto clear_hash;
644 : : if (tcp_md5_hash_header(hp, th))
645 : : goto clear_hash;
646 : : if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2))
647 : : goto clear_hash;
648 : : if (tcp_md5_hash_key(hp, key))
649 : : goto clear_hash;
650 : : if (crypto_hash_final(desc, md5_hash))
651 : : goto clear_hash;
652 : :
653 : : tcp_put_md5sig_pool();
654 : : return 0;
655 : :
656 : : clear_hash:
657 : : tcp_put_md5sig_pool();
658 : : clear_hash_noput:
659 : : memset(md5_hash, 0, 16);
660 : : return 1;
661 : : }
662 : :
663 : : static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
664 : : {
665 : : const __u8 *hash_location = NULL;
666 : : struct tcp_md5sig_key *hash_expected;
667 : : const struct ipv6hdr *ip6h = ipv6_hdr(skb);
668 : : const struct tcphdr *th = tcp_hdr(skb);
669 : : int genhash;
670 : : u8 newhash[16];
671 : :
672 : : hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
673 : : hash_location = tcp_parse_md5sig_option(th);
674 : :
675 : : /* We've parsed the options - do we have a hash? */
676 : : if (!hash_expected && !hash_location)
677 : : return 0;
678 : :
679 : : if (hash_expected && !hash_location) {
680 : : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
681 : : return 1;
682 : : }
683 : :
684 : : if (!hash_expected && hash_location) {
685 : : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
686 : : return 1;
687 : : }
688 : :
689 : : /* check the signature */
690 : : genhash = tcp_v6_md5_hash_skb(newhash,
691 : : hash_expected,
692 : : NULL, NULL, skb);
693 : :
694 : : if (genhash || memcmp(hash_location, newhash, 16) != 0) {
695 : : net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
696 : : genhash ? "failed" : "mismatch",
697 : : &ip6h->saddr, ntohs(th->source),
698 : : &ip6h->daddr, ntohs(th->dest));
699 : : return 1;
700 : : }
701 : : return 0;
702 : : }
703 : : #endif
704 : :
705 : : struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
706 : : .family = AF_INET6,
707 : : .obj_size = sizeof(struct tcp6_request_sock),
708 : : .rtx_syn_ack = tcp_v6_rtx_synack,
709 : : .send_ack = tcp_v6_reqsk_send_ack,
710 : : .destructor = tcp_v6_reqsk_destructor,
711 : : .send_reset = tcp_v6_send_reset,
712 : : .syn_ack_timeout = tcp_syn_ack_timeout,
713 : : };
714 : :
715 : : #ifdef CONFIG_TCP_MD5SIG
716 : : static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
717 : : .md5_lookup = tcp_v6_reqsk_md5_lookup,
718 : : .calc_md5_hash = tcp_v6_md5_hash_skb,
719 : : };
720 : : #endif
721 : :
722 : 0 : static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
723 : : u32 tsval, u32 tsecr,
724 : : struct tcp_md5sig_key *key, int rst, u8 tclass)
725 : : {
726 : : const struct tcphdr *th = tcp_hdr(skb);
727 : : struct tcphdr *t1;
728 : : struct sk_buff *buff;
729 : : struct flowi6 fl6;
730 : : struct net *net = dev_net(skb_dst(skb)->dev);
731 : 0 : struct sock *ctl_sk = net->ipv6.tcp_sk;
732 : : unsigned int tot_len = sizeof(struct tcphdr);
733 : : struct dst_entry *dst;
734 : : __be32 *topt;
735 : :
736 [ # # ]: 0 : if (tsecr)
737 : : tot_len += TCPOLEN_TSTAMP_ALIGNED;
738 : : #ifdef CONFIG_TCP_MD5SIG
739 : : if (key)
740 : : tot_len += TCPOLEN_MD5SIG_ALIGNED;
741 : : #endif
742 : :
743 : 0 : buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
744 : : GFP_ATOMIC);
745 [ # # ]: 0 : if (buff == NULL)
746 : 0 : return;
747 : :
748 : : skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
749 : :
750 : 0 : t1 = (struct tcphdr *) skb_push(buff, tot_len);
751 : : skb_reset_transport_header(buff);
752 : :
753 : : /* Swap the send and the receive. */
754 : 0 : memset(t1, 0, sizeof(*t1));
755 : 0 : t1->dest = th->source;
756 : 0 : t1->source = th->dest;
757 : 0 : t1->doff = tot_len / 4;
758 [ # # ]: 0 : t1->seq = htonl(seq);
759 [ # # ]: 0 : t1->ack_seq = htonl(ack);
760 [ # # ][ # # ]: 0 : t1->ack = !rst || !th->ack;
761 : 0 : t1->rst = rst;
762 [ # # ]: 0 : t1->window = htons(win);
763 : :
764 : : topt = (__be32 *)(t1 + 1);
765 : :
766 [ # # ]: 0 : if (tsecr) {
767 : 0 : *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
768 : : (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
769 [ # # ]: 0 : *topt++ = htonl(tsval);
770 [ # # ]: 0 : *topt++ = htonl(tsecr);
771 : : }
772 : :
773 : : #ifdef CONFIG_TCP_MD5SIG
774 : : if (key) {
775 : : *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
776 : : (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
777 : : tcp_v6_md5_hash_hdr((__u8 *)topt, key,
778 : : &ipv6_hdr(skb)->saddr,
779 : : &ipv6_hdr(skb)->daddr, t1);
780 : : }
781 : : #endif
782 : :
783 : 0 : memset(&fl6, 0, sizeof(fl6));
784 : 0 : fl6.daddr = ipv6_hdr(skb)->saddr;
785 : 0 : fl6.saddr = ipv6_hdr(skb)->daddr;
786 : :
787 : 0 : buff->ip_summed = CHECKSUM_PARTIAL;
788 : 0 : buff->csum = 0;
789 : :
790 : : __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);
791 : :
792 : 0 : fl6.flowi6_proto = IPPROTO_TCP;
793 [ # # ]: 0 : if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
794 : 0 : fl6.flowi6_oif = inet6_iif(skb);
795 : 0 : fl6.fl6_dport = t1->dest;
796 : 0 : fl6.fl6_sport = t1->source;
797 : : security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
798 : :
799 : : /* Pass a socket to ip6_dst_lookup either it is for RST
800 : : * Underlying function will use this to retrieve the network
801 : : * namespace
802 : : */
803 : 0 : dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
804 [ # # ]: 0 : if (!IS_ERR(dst)) {
805 : : skb_dst_set(buff, dst);
806 : 0 : ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass);
807 : 0 : TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
808 [ # # ]: 0 : if (rst)
809 : 0 : TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
810 : : return;
811 : : }
812 : :
813 : 0 : kfree_skb(buff);
814 : : }
815 : :
816 : 0 : static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
817 : : {
818 : : const struct tcphdr *th = tcp_hdr(skb);
819 : : u32 seq = 0, ack_seq = 0;
820 : : struct tcp_md5sig_key *key = NULL;
821 : : #ifdef CONFIG_TCP_MD5SIG
822 : : const __u8 *hash_location = NULL;
823 : : struct ipv6hdr *ipv6h = ipv6_hdr(skb);
824 : : unsigned char newhash[16];
825 : : int genhash;
826 : : struct sock *sk1 = NULL;
827 : : #endif
828 : :
829 [ # # ]: 0 : if (th->rst)
830 : : return;
831 : :
832 [ # # ]: 0 : if (!ipv6_unicast_destination(skb))
833 : : return;
834 : :
835 : : #ifdef CONFIG_TCP_MD5SIG
836 : : hash_location = tcp_parse_md5sig_option(th);
837 : : if (!sk && hash_location) {
838 : : /*
839 : : * active side is lost. Try to find listening socket through
840 : : * source port, and then find md5 key through listening socket.
841 : : * we are not loose security here:
842 : : * Incoming packet is checked with md5 hash with finding key,
843 : : * no RST generated if md5 hash doesn't match.
844 : : */
845 : : sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev),
846 : : &tcp_hashinfo, &ipv6h->saddr,
847 : : th->source, &ipv6h->daddr,
848 : : ntohs(th->source), inet6_iif(skb));
849 : : if (!sk1)
850 : : return;
851 : :
852 : : rcu_read_lock();
853 : : key = tcp_v6_md5_do_lookup(sk1, &ipv6h->saddr);
854 : : if (!key)
855 : : goto release_sk1;
856 : :
857 : : genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, NULL, skb);
858 : : if (genhash || memcmp(hash_location, newhash, 16) != 0)
859 : : goto release_sk1;
860 : : } else {
861 : : key = sk ? tcp_v6_md5_do_lookup(sk, &ipv6h->saddr) : NULL;
862 : : }
863 : : #endif
864 : :
865 [ # # ]: 0 : if (th->ack)
866 [ # # ]: 0 : seq = ntohl(th->ack_seq);
867 : : else
868 [ # # ]: 0 : ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
869 : 0 : (th->doff << 2);
870 : :
871 : 0 : tcp_v6_send_response(skb, seq, ack_seq, 0, 0, 0, key, 1, 0);
872 : :
873 : : #ifdef CONFIG_TCP_MD5SIG
874 : : release_sk1:
875 : : if (sk1) {
876 : : rcu_read_unlock();
877 : : sock_put(sk1);
878 : : }
879 : : #endif
880 : : }
881 : :
882 : : static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
883 : : u32 win, u32 tsval, u32 tsecr,
884 : : struct tcp_md5sig_key *key, u8 tclass)
885 : : {
886 : 0 : tcp_v6_send_response(skb, seq, ack, win, tsval, tsecr, key, 0, tclass);
887 : : }
888 : :
889 : 0 : static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
890 : : {
891 : : struct inet_timewait_sock *tw = inet_twsk(sk);
892 : : struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
893 : :
894 : 0 : tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
895 : 0 : tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
896 : 0 : tcp_time_stamp + tcptw->tw_ts_offset,
897 : : tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw),
898 : : tw->tw_tclass);
899 : :
900 : 0 : inet_twsk_put(tw);
901 : 0 : }
902 : :
903 : 0 : static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
904 : : struct request_sock *req)
905 : : {
906 : 0 : tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1,
907 : : req->rcv_wnd, tcp_time_stamp, req->ts_recent,
908 : : tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0);
909 : 0 : }
910 : :
911 : :
912 : 0 : static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
913 : : {
914 : : struct request_sock *req, **prev;
915 : : const struct tcphdr *th = tcp_hdr(skb);
916 : : struct sock *nsk;
917 : :
918 : : /* Find possible connection requests. */
919 : 0 : req = inet6_csk_search_req(sk, &prev, th->source,
920 : 0 : &ipv6_hdr(skb)->saddr,
921 : 0 : &ipv6_hdr(skb)->daddr, inet6_iif(skb));
922 [ # # ]: 0 : if (req)
923 : 0 : return tcp_check_req(sk, skb, req, prev, false);
924 : :
925 [ # # ]: 0 : nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
926 : 0 : &ipv6_hdr(skb)->saddr, th->source,
927 : 0 : &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb));
928 : :
929 [ # # ]: 0 : if (nsk) {
930 [ # # ]: 0 : if (nsk->sk_state != TCP_TIME_WAIT) {
931 : : bh_lock_sock(nsk);
932 : 0 : return nsk;
933 : : }
934 : 0 : inet_twsk_put(inet_twsk(nsk));
935 : 0 : return NULL;
936 : : }
937 : :
938 : : #ifdef CONFIG_SYN_COOKIES
939 [ # # ]: 0 : if (!th->syn)
940 : 0 : sk = cookie_v6_check(sk, skb);
941 : : #endif
942 : 0 : return sk;
943 : : }
944 : :
945 : : /* FIXME: this is substantially similar to the ipv4 code.
946 : : * Can some kind of merge be done? -- erics
947 : : */
948 : 0 : static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
949 : : {
950 : : struct tcp_options_received tmp_opt;
951 : : struct request_sock *req;
952 : : struct inet_request_sock *ireq;
953 : : struct ipv6_pinfo *np = inet6_sk(sk);
954 : : struct tcp_sock *tp = tcp_sk(sk);
955 : 0 : __u32 isn = TCP_SKB_CB(skb)->when;
956 : : struct dst_entry *dst = NULL;
957 : : struct flowi6 fl6;
958 : : bool want_cookie = false;
959 : :
960 [ # # ]: 0 : if (skb->protocol == htons(ETH_P_IP))
961 : 0 : return tcp_v4_conn_request(sk, skb);
962 : :
963 [ # # ]: 0 : if (!ipv6_unicast_destination(skb))
964 : : goto drop;
965 : :
966 [ # # ][ # # ]: 0 : if ((sysctl_tcp_syncookies == 2 ||
967 [ # # ]: 0 : inet_csk_reqsk_queue_is_full(sk)) && !isn) {
968 : 0 : want_cookie = tcp_syn_flood_action(sk, skb, "TCPv6");
969 [ # # ]: 0 : if (!want_cookie)
970 : : goto drop;
971 : : }
972 : :
973 [ # # ][ # # ]: 0 : if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
974 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
975 : : goto drop;
976 : : }
977 : :
978 : : req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
979 [ # # ]: 0 : if (req == NULL)
980 : : goto drop;
981 : :
982 : : #ifdef CONFIG_TCP_MD5SIG
983 : : tcp_rsk(req)->af_specific = &tcp_request_sock_ipv6_ops;
984 : : #endif
985 : :
986 : : tcp_clear_options(&tmp_opt);
987 : 0 : tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
988 : 0 : tmp_opt.user_mss = tp->rx_opt.user_mss;
989 : 0 : tcp_parse_options(skb, &tmp_opt, 0, NULL);
990 : :
991 [ # # ][ # # ]: 0 : if (want_cookie && !tmp_opt.saw_tstamp)
992 : : tcp_clear_options(&tmp_opt);
993 : :
994 : 0 : tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
995 : : tcp_openreq_init(req, &tmp_opt, skb);
996 : :
997 : : ireq = inet_rsk(req);
998 : 0 : ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
999 : 0 : ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
1000 [ # # ][ # # ]: 0 : if (!want_cookie || tmp_opt.tstamp_ok)
1001 : 0 : TCP_ECN_create_request(req, skb, sock_net(sk));
1002 : :
1003 : 0 : ireq->ir_iif = sk->sk_bound_dev_if;
1004 : :
1005 : : /* So that link locals have meaning */
1006 [ # # # # ]: 0 : if (!sk->sk_bound_dev_if &&
1007 : 0 : ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
1008 : 0 : ireq->ir_iif = inet6_iif(skb);
1009 : :
1010 [ # # ]: 0 : if (!isn) {
1011 [ # # ]: 0 : if (ipv6_opt_accepted(sk, skb) ||
1012 : : np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
1013 [ # # ]: 0 : np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
1014 : 0 : atomic_inc(&skb->users);
1015 : 0 : ireq->pktopts = skb;
1016 : : }
1017 : :
1018 [ # # ]: 0 : if (want_cookie) {
1019 : 0 : isn = cookie_v6_init_sequence(sk, skb, &req->mss);
1020 : 0 : req->cookie_ts = tmp_opt.tstamp_ok;
1021 : 0 : goto have_isn;
1022 : : }
1023 : :
1024 : : /* VJ's idea. We save last timestamp seen
1025 : : * from the destination in peer table, when entering
1026 : : * state TIME-WAIT, and check against it before
1027 : : * accepting new connection request.
1028 : : *
1029 : : * If "isn" is not zero, this request hit alive
1030 : : * timewait bucket, so that all the necessary checks
1031 : : * are made in the function processing timewait state.
1032 : : */
1033 [ # # ][ # # ]: 0 : if (tmp_opt.saw_tstamp &&
1034 [ # # ]: 0 : tcp_death_row.sysctl_tw_recycle &&
1035 : : (dst = inet6_csk_route_req(sk, &fl6, req)) != NULL) {
1036 [ # # ]: 0 : if (!tcp_peer_is_proven(req, dst, true)) {
1037 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
1038 : : goto drop_and_release;
1039 : : }
1040 : : }
1041 : : /* Kill the following clause, if you dislike this way. */
1042 [ # # ][ # # ]: 0 : else if (!sysctl_tcp_syncookies &&
1043 : 0 : (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
1044 [ # # ]: 0 : (sysctl_max_syn_backlog >> 2)) &&
1045 : 0 : !tcp_peer_is_proven(req, dst, false)) {
1046 : : /* Without syncookies last quarter of
1047 : : * backlog is filled with destinations,
1048 : : * proven to be alive.
1049 : : * It means that we continue to communicate
1050 : : * to destinations, already remembered
1051 : : * to the moment of synflood.
1052 : : */
1053 [ # # ][ # # ]: 0 : LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open request from %pI6/%u\n",
1054 : : &ireq->ir_v6_rmt_addr, ntohs(tcp_hdr(skb)->source));
1055 : : goto drop_and_release;
1056 : : }
1057 : :
1058 : 0 : isn = tcp_v6_init_sequence(skb);
1059 : : }
1060 : : have_isn:
1061 : 0 : tcp_rsk(req)->snt_isn = isn;
1062 : :
1063 [ # # ]: 0 : if (security_inet_conn_request(sk, skb, req))
1064 : : goto drop_and_release;
1065 : :
1066 [ # # ]: 0 : if (tcp_v6_send_synack(sk, dst, &fl6, req,
1067 [ # # ]: 0 : skb_get_queue_mapping(skb)) ||
1068 : : want_cookie)
1069 : : goto drop_and_free;
1070 : :
1071 : 0 : tcp_rsk(req)->snt_synack = tcp_time_stamp;
1072 : 0 : tcp_rsk(req)->listener = NULL;
1073 : 0 : inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1074 : 0 : return 0;
1075 : :
1076 : : drop_and_release:
1077 : 0 : dst_release(dst);
1078 : : drop_and_free:
1079 : : reqsk_free(req);
1080 : : drop:
1081 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1082 : 0 : return 0; /* don't send reset */
1083 : : }
1084 : :
1085 : 0 : static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1086 : : struct request_sock *req,
1087 : : struct dst_entry *dst)
1088 : : {
1089 : : struct inet_request_sock *ireq;
1090 : : struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
1091 : : struct tcp6_sock *newtcp6sk;
1092 : : struct inet_sock *newinet;
1093 : : struct tcp_sock *newtp;
1094 : : struct sock *newsk;
1095 : : #ifdef CONFIG_TCP_MD5SIG
1096 : : struct tcp_md5sig_key *key;
1097 : : #endif
1098 : : struct flowi6 fl6;
1099 : :
1100 [ # # ]: 0 : if (skb->protocol == htons(ETH_P_IP)) {
1101 : : /*
1102 : : * v6 mapped
1103 : : */
1104 : :
1105 : 0 : newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst);
1106 : :
1107 [ # # ]: 0 : if (newsk == NULL)
1108 : : return NULL;
1109 : :
1110 : : newtcp6sk = (struct tcp6_sock *)newsk;
1111 : 0 : inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
1112 : :
1113 : : newinet = inet_sk(newsk);
1114 : : newnp = inet6_sk(newsk);
1115 : : newtp = tcp_sk(newsk);
1116 : :
1117 : 0 : memcpy(newnp, np, sizeof(struct ipv6_pinfo));
1118 : :
1119 : 0 : ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
1120 : :
1121 : 0 : ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
1122 : :
1123 : 0 : newsk->sk_v6_rcv_saddr = newnp->saddr;
1124 : :
1125 : 0 : inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
1126 : 0 : newsk->sk_backlog_rcv = tcp_v4_do_rcv;
1127 : : #ifdef CONFIG_TCP_MD5SIG
1128 : : newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
1129 : : #endif
1130 : :
1131 : 0 : newnp->ipv6_ac_list = NULL;
1132 : 0 : newnp->ipv6_fl_list = NULL;
1133 : 0 : newnp->pktoptions = NULL;
1134 : 0 : newnp->opt = NULL;
1135 : 0 : newnp->mcast_oif = inet6_iif(skb);
1136 : 0 : newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
1137 : 0 : newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
1138 : :
1139 : : /*
1140 : : * No need to charge this sock to the relevant IPv6 refcnt debug socks count
1141 : : * here, tcp_create_openreq_child now does this for us, see the comment in
1142 : : * that function for the gory details. -acme
1143 : : */
1144 : :
1145 : : /* It is tricky place. Until this moment IPv4 tcp
1146 : : worked with IPv6 icsk.icsk_af_ops.
1147 : : Sync it now.
1148 : : */
1149 : 0 : tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
1150 : :
1151 : 0 : return newsk;
1152 : : }
1153 : :
1154 : : ireq = inet_rsk(req);
1155 : :
1156 [ # # ]: 0 : if (sk_acceptq_is_full(sk))
1157 : : goto out_overflow;
1158 : :
1159 [ # # ]: 0 : if (!dst) {
1160 : 0 : dst = inet6_csk_route_req(sk, &fl6, req);
1161 [ # # ]: 0 : if (!dst)
1162 : : goto out;
1163 : : }
1164 : :
1165 : 0 : newsk = tcp_create_openreq_child(sk, req, skb);
1166 [ # # ]: 0 : if (newsk == NULL)
1167 : : goto out_nonewsk;
1168 : :
1169 : : /*
1170 : : * No need to charge this sock to the relevant IPv6 refcnt debug socks
1171 : : * count here, tcp_create_openreq_child now does this for us, see the
1172 : : * comment in that function for the gory details. -acme
1173 : : */
1174 : :
1175 : 0 : newsk->sk_gso_type = SKB_GSO_TCPV6;
1176 : : __ip6_dst_store(newsk, dst, NULL, NULL);
1177 : 0 : inet6_sk_rx_dst_set(newsk, skb);
1178 : :
1179 : : newtcp6sk = (struct tcp6_sock *)newsk;
1180 : 0 : inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
1181 : :
1182 : : newtp = tcp_sk(newsk);
1183 : : newinet = inet_sk(newsk);
1184 : : newnp = inet6_sk(newsk);
1185 : :
1186 : 0 : memcpy(newnp, np, sizeof(struct ipv6_pinfo));
1187 : :
1188 : 0 : newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr;
1189 : 0 : newnp->saddr = ireq->ir_v6_loc_addr;
1190 : 0 : newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr;
1191 : 0 : newsk->sk_bound_dev_if = ireq->ir_iif;
1192 : :
1193 : : /* Now IPv6 options...
1194 : :
1195 : : First: no IPv4 options.
1196 : : */
1197 : 0 : newinet->inet_opt = NULL;
1198 : 0 : newnp->ipv6_ac_list = NULL;
1199 : 0 : newnp->ipv6_fl_list = NULL;
1200 : :
1201 : : /* Clone RX bits */
1202 : 0 : newnp->rxopt.all = np->rxopt.all;
1203 : :
1204 : : /* Clone pktoptions received with SYN */
1205 : 0 : newnp->pktoptions = NULL;
1206 [ # # ]: 0 : if (ireq->pktopts != NULL) {
1207 : 0 : newnp->pktoptions = skb_clone(ireq->pktopts,
1208 : : sk_gfp_atomic(sk, GFP_ATOMIC));
1209 : 0 : consume_skb(ireq->pktopts);
1210 : 0 : ireq->pktopts = NULL;
1211 [ # # ]: 0 : if (newnp->pktoptions)
1212 : : skb_set_owner_r(newnp->pktoptions, newsk);
1213 : : }
1214 : 0 : newnp->opt = NULL;
1215 : 0 : newnp->mcast_oif = inet6_iif(skb);
1216 : 0 : newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
1217 : 0 : newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
1218 : :
1219 : : /* Clone native IPv6 options from listening socket (if any)
1220 : :
1221 : : Yes, keeping reference count would be much more clever,
1222 : : but we make one more one thing there: reattach optmem
1223 : : to newsk.
1224 : : */
1225 [ # # ]: 0 : if (np->opt)
1226 : 0 : newnp->opt = ipv6_dup_options(newsk, np->opt);
1227 : :
1228 : 0 : inet_csk(newsk)->icsk_ext_hdr_len = 0;
1229 [ # # ]: 0 : if (newnp->opt)
1230 : 0 : inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
1231 : 0 : newnp->opt->opt_flen);
1232 : :
1233 : 0 : tcp_mtup_init(newsk);
1234 : 0 : tcp_sync_mss(newsk, dst_mtu(dst));
1235 : 0 : newtp->advmss = dst_metric_advmss(dst);
1236 [ # # ][ # # ]: 0 : if (tcp_sk(sk)->rx_opt.user_mss &&
1237 : : tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
1238 : 0 : newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1239 : :
1240 : 0 : tcp_initialize_rcv_mss(newsk);
1241 : :
1242 : 0 : newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
1243 : 0 : newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
1244 : :
1245 : : #ifdef CONFIG_TCP_MD5SIG
1246 : : /* Copy over the MD5 key from the original socket */
1247 : : if ((key = tcp_v6_md5_do_lookup(sk, &newsk->sk_v6_daddr)) != NULL) {
1248 : : /* We're using one, so create a matching key
1249 : : * on the newsk structure. If we fail to get
1250 : : * memory, then we end up not copying the key
1251 : : * across. Shucks.
1252 : : */
1253 : : tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr,
1254 : : AF_INET6, key->key, key->keylen,
1255 : : sk_gfp_atomic(sk, GFP_ATOMIC));
1256 : : }
1257 : : #endif
1258 : :
1259 [ # # ]: 0 : if (__inet_inherit_port(sk, newsk) < 0) {
1260 : 0 : inet_csk_prepare_forced_close(newsk);
1261 : 0 : tcp_done(newsk);
1262 : 0 : goto out;
1263 : : }
1264 : 0 : __inet6_hash(newsk, NULL);
1265 : :
1266 : 0 : return newsk;
1267 : :
1268 : : out_overflow:
1269 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
1270 : : out_nonewsk:
1271 : 0 : dst_release(dst);
1272 : : out:
1273 : 0 : NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1274 : 0 : return NULL;
1275 : : }
1276 : :
1277 : 0 : static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
1278 : : {
1279 [ # # ]: 0 : if (skb->ip_summed == CHECKSUM_COMPLETE) {
1280 [ # # ]: 0 : if (!tcp_v6_check(skb->len, &ipv6_hdr(skb)->saddr,
1281 : 0 : &ipv6_hdr(skb)->daddr, skb->csum)) {
1282 : 0 : skb->ip_summed = CHECKSUM_UNNECESSARY;
1283 : 0 : return 0;
1284 : : }
1285 : : }
1286 : :
1287 : 0 : skb->csum = ~csum_unfold(tcp_v6_check(skb->len,
1288 : 0 : &ipv6_hdr(skb)->saddr,
1289 : 0 : &ipv6_hdr(skb)->daddr, 0));
1290 : :
1291 [ # # ]: 0 : if (skb->len <= 76) {
1292 : 0 : return __skb_checksum_complete(skb);
1293 : : }
1294 : : return 0;
1295 : : }
1296 : :
1297 : : /* The socket must have it's spinlock held when we get
1298 : : * here.
1299 : : *
1300 : : * We have a potential double-lock case here, so even when
1301 : : * doing backlog processing we use the BH locking scheme.
1302 : : * This is because we cannot sleep with the original spinlock
1303 : : * held.
1304 : : */
1305 : 0 : static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1306 : : {
1307 : : struct ipv6_pinfo *np = inet6_sk(sk);
1308 : : struct tcp_sock *tp;
1309 : : struct sk_buff *opt_skb = NULL;
1310 : :
1311 : : /* Imagine: socket is IPv6. IPv4 packet arrives,
1312 : : goes to IPv4 receive handler and backlogged.
1313 : : From backlog it always goes here. Kerboom...
1314 : : Fortunately, tcp_rcv_established and rcv_established
1315 : : handle them correctly, but it is not case with
1316 : : tcp_v6_hnd_req and tcp_v6_send_reset(). --ANK
1317 : : */
1318 : :
1319 [ # # ]: 0 : if (skb->protocol == htons(ETH_P_IP))
1320 : 0 : return tcp_v4_do_rcv(sk, skb);
1321 : :
1322 : : #ifdef CONFIG_TCP_MD5SIG
1323 : : if (tcp_v6_inbound_md5_hash (sk, skb))
1324 : : goto discard;
1325 : : #endif
1326 : :
1327 [ # # ]: 0 : if (sk_filter(sk, skb))
1328 : : goto discard;
1329 : :
1330 : : /*
1331 : : * socket locking is here for SMP purposes as backlog rcv
1332 : : * is currently called with bh processing disabled.
1333 : : */
1334 : :
1335 : : /* Do Stevens' IPV6_PKTOPTIONS.
1336 : :
1337 : : Yes, guys, it is the only place in our code, where we
1338 : : may make it not affecting IPv4.
1339 : : The rest of code is protocol independent,
1340 : : and I do not like idea to uglify IPv4.
1341 : :
1342 : : Actually, all the idea behind IPV6_PKTOPTIONS
1343 : : looks not very well thought. For now we latch
1344 : : options, received in the last packet, enqueued
1345 : : by tcp. Feel free to propose better solution.
1346 : : --ANK (980728)
1347 : : */
1348 [ # # ]: 0 : if (np->rxopt.all)
1349 : 0 : opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC));
1350 : :
1351 [ # # ]: 0 : if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1352 : 0 : struct dst_entry *dst = sk->sk_rx_dst;
1353 : :
1354 : : sock_rps_save_rxhash(sk, skb);
1355 [ # # ]: 0 : if (dst) {
1356 [ # # # # ]: 0 : if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
1357 : 0 : dst->ops->check(dst, np->rx_dst_cookie) == NULL) {
1358 : 0 : dst_release(dst);
1359 : 0 : sk->sk_rx_dst = NULL;
1360 : : }
1361 : : }
1362 : :
1363 : 0 : tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len);
1364 [ # # ]: 0 : if (opt_skb)
1365 : : goto ipv6_pktoptions;
1366 : : return 0;
1367 : : }
1368 : :
1369 [ # # ][ # # ]: 0 : if (skb->len < tcp_hdrlen(skb) || tcp_checksum_complete(skb))
1370 : : goto csum_err;
1371 : :
1372 [ # # ]: 0 : if (sk->sk_state == TCP_LISTEN) {
1373 : 0 : struct sock *nsk = tcp_v6_hnd_req(sk, skb);
1374 [ # # ]: 0 : if (!nsk)
1375 : : goto discard;
1376 : :
1377 : : /*
1378 : : * Queue it on the new socket if the new socket is active,
1379 : : * otherwise we just shortcircuit this and continue with
1380 : : * the new socket..
1381 : : */
1382 [ # # ]: 0 : if(nsk != sk) {
1383 : : sock_rps_save_rxhash(nsk, skb);
1384 [ # # ]: 0 : if (tcp_child_process(sk, nsk, skb))
1385 : : goto reset;
1386 [ # # ]: 0 : if (opt_skb)
1387 : 0 : __kfree_skb(opt_skb);
1388 : : return 0;
1389 : : }
1390 : : } else
1391 : : sock_rps_save_rxhash(sk, skb);
1392 : :
1393 [ # # ]: 0 : if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len))
1394 : : goto reset;
1395 [ # # ]: 0 : if (opt_skb)
1396 : : goto ipv6_pktoptions;
1397 : : return 0;
1398 : :
1399 : : reset:
1400 : 0 : tcp_v6_send_reset(sk, skb);
1401 : : discard:
1402 [ # # ]: 0 : if (opt_skb)
1403 : 0 : __kfree_skb(opt_skb);
1404 : 0 : kfree_skb(skb);
1405 : 0 : return 0;
1406 : : csum_err:
1407 : 0 : TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
1408 : 0 : TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
1409 : : goto discard;
1410 : :
1411 : :
1412 : : ipv6_pktoptions:
1413 : : /* Do you ask, what is it?
1414 : :
1415 : : 1. skb was enqueued by tcp.
1416 : : 2. skb is added to tail of read queue, rather than out of order.
1417 : : 3. socket is not in passive state.
1418 : : 4. Finally, it really contains options, which user wants to receive.
1419 : : */
1420 : : tp = tcp_sk(sk);
1421 [ # # ][ # # ]: 0 : if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
1422 : 0 : !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
1423 [ # # ]: 0 : if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
1424 : 0 : np->mcast_oif = inet6_iif(opt_skb);
1425 [ # # ]: 0 : if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
1426 : 0 : np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
1427 [ # # ]: 0 : if (np->rxopt.bits.rxtclass)
1428 : 0 : np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(opt_skb));
1429 [ # # ]: 0 : if (ipv6_opt_accepted(sk, opt_skb)) {
1430 : : skb_set_owner_r(opt_skb, sk);
1431 : 0 : opt_skb = xchg(&np->pktoptions, opt_skb);
1432 : : } else {
1433 : 0 : __kfree_skb(opt_skb);
1434 : 0 : opt_skb = xchg(&np->pktoptions, NULL);
1435 : : }
1436 : : }
1437 : :
1438 : 0 : kfree_skb(opt_skb);
1439 : 0 : return 0;
1440 : : }
1441 : :
1442 : 0 : static int tcp_v6_rcv(struct sk_buff *skb)
1443 : : {
1444 : : const struct tcphdr *th;
1445 : : const struct ipv6hdr *hdr;
1446 : : struct sock *sk;
1447 : : int ret;
1448 : : struct net *net = dev_net(skb->dev);
1449 : :
1450 [ # # ]: 0 : if (skb->pkt_type != PACKET_HOST)
1451 : : goto discard_it;
1452 : :
1453 : : /*
1454 : : * Count it even if it's bad.
1455 : : */
1456 : 0 : TCP_INC_STATS_BH(net, TCP_MIB_INSEGS);
1457 : :
1458 [ # # ]: 0 : if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
1459 : : goto discard_it;
1460 : :
1461 : : th = tcp_hdr(skb);
1462 : :
1463 [ # # ]: 0 : if (th->doff < sizeof(struct tcphdr)/4)
1464 : : goto bad_packet;
1465 [ # # ]: 0 : if (!pskb_may_pull(skb, th->doff*4))
1466 : : goto discard_it;
1467 : :
1468 [ # # ][ # # ]: 0 : if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
1469 : : goto csum_error;
1470 : :
1471 : : th = tcp_hdr(skb);
1472 : : hdr = ipv6_hdr(skb);
1473 [ # # ]: 0 : TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1474 : 0 : TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1475 : 0 : skb->len - th->doff*4);
1476 [ # # ]: 0 : TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1477 : 0 : TCP_SKB_CB(skb)->when = 0;
1478 : 0 : TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
1479 : 0 : TCP_SKB_CB(skb)->sacked = 0;
1480 : :
1481 : 0 : sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
1482 [ # # ]: 0 : if (!sk)
1483 : : goto no_tcp_socket;
1484 : :
1485 : : process:
1486 [ # # ]: 0 : if (sk->sk_state == TCP_TIME_WAIT)
1487 : : goto do_time_wait;
1488 : :
1489 [ # # ]: 0 : if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
1490 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
1491 : : goto discard_and_relse;
1492 : : }
1493 : :
1494 [ # # ]: 0 : if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1495 : : goto discard_and_relse;
1496 : :
1497 [ # # ]: 0 : if (sk_filter(sk, skb))
1498 : : goto discard_and_relse;
1499 : :
1500 : : sk_mark_napi_id(sk, skb);
1501 : 0 : skb->dev = NULL;
1502 : :
1503 : 0 : bh_lock_sock_nested(sk);
1504 : : ret = 0;
1505 [ # # ]: 0 : if (!sock_owned_by_user(sk)) {
1506 : : #ifdef CONFIG_NET_DMA
1507 : : struct tcp_sock *tp = tcp_sk(sk);
1508 : : if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
1509 : : tp->ucopy.dma_chan = net_dma_find_channel();
1510 : : if (tp->ucopy.dma_chan)
1511 : : ret = tcp_v6_do_rcv(sk, skb);
1512 : : else
1513 : : #endif
1514 : : {
1515 [ # # ]: 0 : if (!tcp_prequeue(sk, skb))
1516 : 0 : ret = tcp_v6_do_rcv(sk, skb);
1517 : : }
1518 [ # # ]: 0 : } else if (unlikely(sk_add_backlog(sk, skb,
1519 : : sk->sk_rcvbuf + sk->sk_sndbuf))) {
1520 : : bh_unlock_sock(sk);
1521 : 0 : NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
1522 : : goto discard_and_relse;
1523 : : }
1524 : : bh_unlock_sock(sk);
1525 : :
1526 : : sock_put(sk);
1527 [ # # ]: 0 : return ret ? -1 : 0;
1528 : :
1529 : : no_tcp_socket:
1530 [ # # ]: 0 : if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1531 : : goto discard_it;
1532 : :
1533 [ # # ][ # # ]: 0 : if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1534 : : csum_error:
1535 : 0 : TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
1536 : : bad_packet:
1537 : 0 : TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
1538 : : } else {
1539 : 0 : tcp_v6_send_reset(NULL, skb);
1540 : : }
1541 : :
1542 : : discard_it:
1543 : 0 : kfree_skb(skb);
1544 : 0 : return 0;
1545 : :
1546 : : discard_and_relse:
1547 : : sock_put(sk);
1548 : : goto discard_it;
1549 : :
1550 : : do_time_wait:
1551 [ # # ]: 0 : if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
1552 : 0 : inet_twsk_put(inet_twsk(sk));
1553 : 0 : goto discard_it;
1554 : : }
1555 : :
1556 [ # # ]: 0 : if (skb->len < (th->doff<<2)) {
1557 : 0 : inet_twsk_put(inet_twsk(sk));
1558 : 0 : goto bad_packet;
1559 : : }
1560 [ # # ]: 0 : if (tcp_checksum_complete(skb)) {
1561 : 0 : inet_twsk_put(inet_twsk(sk));
1562 : 0 : goto csum_error;
1563 : : }
1564 : :
1565 [ # # # # ]: 0 : switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
1566 : : case TCP_TW_SYN:
1567 : : {
1568 : : struct sock *sk2;
1569 : :
1570 [ # # ]: 0 : sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo,
1571 : 0 : &ipv6_hdr(skb)->saddr, th->source,
1572 : 0 : &ipv6_hdr(skb)->daddr,
1573 : 0 : ntohs(th->dest), inet6_iif(skb));
1574 [ # # ]: 0 : if (sk2 != NULL) {
1575 : : struct inet_timewait_sock *tw = inet_twsk(sk);
1576 : 0 : inet_twsk_deschedule(tw, &tcp_death_row);
1577 : 0 : inet_twsk_put(tw);
1578 : : sk = sk2;
1579 : 0 : goto process;
1580 : : }
1581 : : /* Fall through to ACK */
1582 : : }
1583 : : case TCP_TW_ACK:
1584 : 0 : tcp_v6_timewait_ack(sk, skb);
1585 : 0 : break;
1586 : : case TCP_TW_RST:
1587 : : goto no_tcp_socket;
1588 : : case TCP_TW_SUCCESS:;
1589 : : }
1590 : : goto discard_it;
1591 : : }
1592 : :
1593 : 0 : static void tcp_v6_early_demux(struct sk_buff *skb)
1594 : : {
1595 : : const struct ipv6hdr *hdr;
1596 : : const struct tcphdr *th;
1597 : : struct sock *sk;
1598 : :
1599 [ # # ]: 0 : if (skb->pkt_type != PACKET_HOST)
1600 : : return;
1601 : :
1602 [ # # ]: 0 : if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr)))
1603 : : return;
1604 : :
1605 : : hdr = ipv6_hdr(skb);
1606 : : th = tcp_hdr(skb);
1607 : :
1608 [ # # ]: 0 : if (th->doff < sizeof(struct tcphdr) / 4)
1609 : : return;
1610 : :
1611 [ # # ]: 0 : sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
1612 : : &hdr->saddr, th->source,
1613 : 0 : &hdr->daddr, ntohs(th->dest),
1614 : : inet6_iif(skb));
1615 [ # # ]: 0 : if (sk) {
1616 : 0 : skb->sk = sk;
1617 : 0 : skb->destructor = sock_edemux;
1618 [ # # ]: 0 : if (sk->sk_state != TCP_TIME_WAIT) {
1619 : 0 : struct dst_entry *dst = sk->sk_rx_dst;
1620 : :
1621 [ # # ]: 0 : if (dst)
1622 : 0 : dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie);
1623 [ # # ][ # # ]: 0 : if (dst &&
1624 : 0 : inet_sk(sk)->rx_dst_ifindex == skb->skb_iif)
1625 : : skb_dst_set_noref(skb, dst);
1626 : : }
1627 : : }
1628 : : }
1629 : :
1630 : : static struct timewait_sock_ops tcp6_timewait_sock_ops = {
1631 : : .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
1632 : : .twsk_unique = tcp_twsk_unique,
1633 : : .twsk_destructor= tcp_twsk_destructor,
1634 : : };
1635 : :
1636 : : static const struct inet_connection_sock_af_ops ipv6_specific = {
1637 : : .queue_xmit = inet6_csk_xmit,
1638 : : .send_check = tcp_v6_send_check,
1639 : : .rebuild_header = inet6_sk_rebuild_header,
1640 : : .sk_rx_dst_set = inet6_sk_rx_dst_set,
1641 : : .conn_request = tcp_v6_conn_request,
1642 : : .syn_recv_sock = tcp_v6_syn_recv_sock,
1643 : : .net_header_len = sizeof(struct ipv6hdr),
1644 : : .net_frag_header_len = sizeof(struct frag_hdr),
1645 : : .setsockopt = ipv6_setsockopt,
1646 : : .getsockopt = ipv6_getsockopt,
1647 : : .addr2sockaddr = inet6_csk_addr2sockaddr,
1648 : : .sockaddr_len = sizeof(struct sockaddr_in6),
1649 : : .bind_conflict = inet6_csk_bind_conflict,
1650 : : #ifdef CONFIG_COMPAT
1651 : : .compat_setsockopt = compat_ipv6_setsockopt,
1652 : : .compat_getsockopt = compat_ipv6_getsockopt,
1653 : : #endif
1654 : : };
1655 : :
1656 : : #ifdef CONFIG_TCP_MD5SIG
1657 : : static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
1658 : : .md5_lookup = tcp_v6_md5_lookup,
1659 : : .calc_md5_hash = tcp_v6_md5_hash_skb,
1660 : : .md5_parse = tcp_v6_parse_md5_keys,
1661 : : };
1662 : : #endif
1663 : :
1664 : : /*
1665 : : * TCP over IPv4 via INET6 API
1666 : : */
1667 : :
1668 : : static const struct inet_connection_sock_af_ops ipv6_mapped = {
1669 : : .queue_xmit = ip_queue_xmit,
1670 : : .send_check = tcp_v4_send_check,
1671 : : .rebuild_header = inet_sk_rebuild_header,
1672 : : .sk_rx_dst_set = inet_sk_rx_dst_set,
1673 : : .conn_request = tcp_v6_conn_request,
1674 : : .syn_recv_sock = tcp_v6_syn_recv_sock,
1675 : : .net_header_len = sizeof(struct iphdr),
1676 : : .setsockopt = ipv6_setsockopt,
1677 : : .getsockopt = ipv6_getsockopt,
1678 : : .addr2sockaddr = inet6_csk_addr2sockaddr,
1679 : : .sockaddr_len = sizeof(struct sockaddr_in6),
1680 : : .bind_conflict = inet6_csk_bind_conflict,
1681 : : #ifdef CONFIG_COMPAT
1682 : : .compat_setsockopt = compat_ipv6_setsockopt,
1683 : : .compat_getsockopt = compat_ipv6_getsockopt,
1684 : : #endif
1685 : : };
1686 : :
1687 : : #ifdef CONFIG_TCP_MD5SIG
1688 : : static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
1689 : : .md5_lookup = tcp_v4_md5_lookup,
1690 : : .calc_md5_hash = tcp_v4_md5_hash_skb,
1691 : : .md5_parse = tcp_v6_parse_md5_keys,
1692 : : };
1693 : : #endif
1694 : :
1695 : : /* NOTE: A lot of things set to zero explicitly by call to
1696 : : * sk_alloc() so need not be done here.
1697 : : */
1698 : 0 : static int tcp_v6_init_sock(struct sock *sk)
1699 : : {
1700 : : struct inet_connection_sock *icsk = inet_csk(sk);
1701 : :
1702 : 1 : tcp_init_sock(sk);
1703 : :
1704 : 1 : icsk->icsk_af_ops = &ipv6_specific;
1705 : :
1706 : : #ifdef CONFIG_TCP_MD5SIG
1707 : : tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific;
1708 : : #endif
1709 : :
1710 : 1 : return 0;
1711 : : }
1712 : :
1713 : 0 : static void tcp_v6_destroy_sock(struct sock *sk)
1714 : : {
1715 : 1 : tcp_v4_destroy_sock(sk);
1716 : 1 : inet6_destroy_sock(sk);
1717 : 1 : }
1718 : :
1719 : : #ifdef CONFIG_PROC_FS
1720 : : /* Proc filesystem TCPv6 sock list dumping. */
1721 : 0 : static void get_openreq6(struct seq_file *seq,
1722 : : const struct sock *sk, struct request_sock *req, int i, kuid_t uid)
1723 : : {
1724 : 0 : int ttd = req->expires - jiffies;
1725 : : const struct in6_addr *src = &inet_rsk(req)->ir_v6_loc_addr;
1726 : : const struct in6_addr *dest = &inet_rsk(req)->ir_v6_rmt_addr;
1727 : :
1728 [ # # ]: 0 : if (ttd < 0)
1729 : : ttd = 0;
1730 : :
1731 : 0 : seq_printf(seq,
1732 : : "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1733 : : "%02X %08X:%08X %02X:%08lX %08X %5u %8d %d %d %pK\n",
1734 : : i,
1735 : : src->s6_addr32[0], src->s6_addr32[1],
1736 : : src->s6_addr32[2], src->s6_addr32[3],
1737 : 0 : inet_rsk(req)->ir_num,
1738 : : dest->s6_addr32[0], dest->s6_addr32[1],
1739 : : dest->s6_addr32[2], dest->s6_addr32[3],
1740 : 0 : ntohs(inet_rsk(req)->ir_rmt_port),
1741 : : TCP_SYN_RECV,
1742 : : 0,0, /* could print option size, but that is af dependent. */
1743 : : 1, /* timers active (only the expire timer) */
1744 : : jiffies_to_clock_t(ttd),
1745 : 0 : req->num_timeout,
1746 : : from_kuid_munged(seq_user_ns(seq), uid),
1747 : : 0, /* non standard timer */
1748 : : 0, /* open_requests have no inode */
1749 : : 0, req);
1750 : 0 : }
1751 : :
1752 : 0 : static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1753 : : {
1754 : : const struct in6_addr *dest, *src;
1755 : : __u16 destp, srcp;
1756 : : int timer_active;
1757 : : unsigned long timer_expires;
1758 : : const struct inet_sock *inet = inet_sk(sp);
1759 : : const struct tcp_sock *tp = tcp_sk(sp);
1760 : : const struct inet_connection_sock *icsk = inet_csk(sp);
1761 : :
1762 : : dest = &sp->sk_v6_daddr;
1763 : : src = &sp->sk_v6_rcv_saddr;
1764 [ - + ]: 1 : destp = ntohs(inet->inet_dport);
1765 [ - + ]: 1 : srcp = ntohs(inet->inet_sport);
1766 : :
1767 [ - + ]: 1 : if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
1768 : : timer_active = 1;
1769 : 0 : timer_expires = icsk->icsk_timeout;
1770 [ - + ]: 1 : } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
1771 : : timer_active = 4;
1772 : 0 : timer_expires = icsk->icsk_timeout;
1773 [ - + ]: 1 : } else if (timer_pending(&sp->sk_timer)) {
1774 : : timer_active = 2;
1775 : 0 : timer_expires = sp->sk_timer.expires;
1776 : : } else {
1777 : : timer_active = 0;
1778 : 1 : timer_expires = jiffies;
1779 : : }
1780 : :
1781 [ + - ][ - + ]: 3 : seq_printf(seq,
1782 : : "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1783 : : "%02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %lu %lu %u %u %d\n",
1784 : : i,
1785 : : src->s6_addr32[0], src->s6_addr32[1],
1786 : : src->s6_addr32[2], src->s6_addr32[3], srcp,
1787 : : dest->s6_addr32[0], dest->s6_addr32[1],
1788 : : dest->s6_addr32[2], dest->s6_addr32[3], destp,
1789 : 1 : sp->sk_state,
1790 : 1 : tp->write_seq-tp->snd_una,
1791 : 2 : (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1792 : : timer_active,
1793 : 1 : jiffies_delta_to_clock_t(timer_expires - jiffies),
1794 : 1 : icsk->icsk_retransmits,
1795 : : from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1796 : 1 : icsk->icsk_probes_out,
1797 : : sock_i_ino(sp),
1798 : : atomic_read(&sp->sk_refcnt), sp,
1799 : 1 : jiffies_to_clock_t(icsk->icsk_rto),
1800 : 1 : jiffies_to_clock_t(icsk->icsk_ack.ato),
1801 : 1 : (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
1802 : : tp->snd_cwnd,
1803 : : tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh
1804 : : );
1805 : 1 : }
1806 : :
1807 : 0 : static void get_timewait6_sock(struct seq_file *seq,
1808 : : struct inet_timewait_sock *tw, int i)
1809 : : {
1810 : : const struct in6_addr *dest, *src;
1811 : : __u16 destp, srcp;
1812 : 0 : s32 delta = tw->tw_ttd - inet_tw_time_stamp();
1813 : :
1814 : : dest = &tw->tw_v6_daddr;
1815 : : src = &tw->tw_v6_rcv_saddr;
1816 [ # # ]: 0 : destp = ntohs(tw->tw_dport);
1817 [ # # ]: 0 : srcp = ntohs(tw->tw_sport);
1818 : :
1819 : 0 : seq_printf(seq,
1820 : : "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1821 : : "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK\n",
1822 : : i,
1823 : : src->s6_addr32[0], src->s6_addr32[1],
1824 : : src->s6_addr32[2], src->s6_addr32[3], srcp,
1825 : : dest->s6_addr32[0], dest->s6_addr32[1],
1826 : : dest->s6_addr32[2], dest->s6_addr32[3], destp,
1827 : 0 : tw->tw_substate, 0, 0,
1828 : : 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
1829 : : atomic_read(&tw->tw_refcnt), tw);
1830 : 0 : }
1831 : :
1832 : 0 : static int tcp6_seq_show(struct seq_file *seq, void *v)
1833 : : {
1834 : : struct tcp_iter_state *st;
1835 : : struct sock *sk = v;
1836 : :
1837 [ + + ]: 2 : if (v == SEQ_START_TOKEN) {
1838 : 1 : seq_puts(seq,
1839 : : " sl "
1840 : : "local_address "
1841 : : "remote_address "
1842 : : "st tx_queue rx_queue tr tm->when retrnsmt"
1843 : : " uid timeout inode\n");
1844 : 1 : goto out;
1845 : : }
1846 : 1 : st = seq->private;
1847 : :
1848 [ + - - ]: 1 : switch (st->state) {
1849 : : case TCP_SEQ_STATE_LISTENING:
1850 : : case TCP_SEQ_STATE_ESTABLISHED:
1851 [ - + ]: 1 : if (sk->sk_state == TCP_TIME_WAIT)
1852 : 0 : get_timewait6_sock(seq, v, st->num);
1853 : : else
1854 : 1 : get_tcp6_sock(seq, v, st->num);
1855 : : break;
1856 : : case TCP_SEQ_STATE_OPENREQ:
1857 : 0 : get_openreq6(seq, st->syn_wait_sk, v, st->num, st->uid);
1858 : 0 : break;
1859 : : }
1860 : : out:
1861 : 0 : return 0;
1862 : : }
1863 : :
1864 : : static const struct file_operations tcp6_afinfo_seq_fops = {
1865 : : .owner = THIS_MODULE,
1866 : : .open = tcp_seq_open,
1867 : : .read = seq_read,
1868 : : .llseek = seq_lseek,
1869 : : .release = seq_release_net
1870 : : };
1871 : :
1872 : : static struct tcp_seq_afinfo tcp6_seq_afinfo = {
1873 : : .name = "tcp6",
1874 : : .family = AF_INET6,
1875 : : .seq_fops = &tcp6_afinfo_seq_fops,
1876 : : .seq_ops = {
1877 : : .show = tcp6_seq_show,
1878 : : },
1879 : : };
1880 : :
1881 : 0 : int __net_init tcp6_proc_init(struct net *net)
1882 : : {
1883 : 0 : return tcp_proc_register(net, &tcp6_seq_afinfo);
1884 : : }
1885 : :
1886 : 0 : void tcp6_proc_exit(struct net *net)
1887 : : {
1888 : 0 : tcp_proc_unregister(net, &tcp6_seq_afinfo);
1889 : 0 : }
1890 : : #endif
1891 : :
1892 : 0 : static void tcp_v6_clear_sk(struct sock *sk, int size)
1893 : : {
1894 : : struct inet_sock *inet = inet_sk(sk);
1895 : :
1896 : : /* we do not want to clear pinet6 field, because of RCU lookups */
1897 : : sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6));
1898 : :
1899 : 1 : size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
1900 [ + - ]: 1 : memset(&inet->pinet6 + 1, 0, size);
1901 : 0 : }
1902 : :
1903 : : struct proto tcpv6_prot = {
1904 : : .name = "TCPv6",
1905 : : .owner = THIS_MODULE,
1906 : : .close = tcp_close,
1907 : : .connect = tcp_v6_connect,
1908 : : .disconnect = tcp_disconnect,
1909 : : .accept = inet_csk_accept,
1910 : : .ioctl = tcp_ioctl,
1911 : : .init = tcp_v6_init_sock,
1912 : : .destroy = tcp_v6_destroy_sock,
1913 : : .shutdown = tcp_shutdown,
1914 : : .setsockopt = tcp_setsockopt,
1915 : : .getsockopt = tcp_getsockopt,
1916 : : .recvmsg = tcp_recvmsg,
1917 : : .sendmsg = tcp_sendmsg,
1918 : : .sendpage = tcp_sendpage,
1919 : : .backlog_rcv = tcp_v6_do_rcv,
1920 : : .release_cb = tcp_release_cb,
1921 : : .mtu_reduced = tcp_v6_mtu_reduced,
1922 : : .hash = tcp_v6_hash,
1923 : : .unhash = inet_unhash,
1924 : : .get_port = inet_csk_get_port,
1925 : : .enter_memory_pressure = tcp_enter_memory_pressure,
1926 : : .stream_memory_free = tcp_stream_memory_free,
1927 : : .sockets_allocated = &tcp_sockets_allocated,
1928 : : .memory_allocated = &tcp_memory_allocated,
1929 : : .memory_pressure = &tcp_memory_pressure,
1930 : : .orphan_count = &tcp_orphan_count,
1931 : : .sysctl_mem = sysctl_tcp_mem,
1932 : : .sysctl_wmem = sysctl_tcp_wmem,
1933 : : .sysctl_rmem = sysctl_tcp_rmem,
1934 : : .max_header = MAX_TCP_HEADER,
1935 : : .obj_size = sizeof(struct tcp6_sock),
1936 : : .slab_flags = SLAB_DESTROY_BY_RCU,
1937 : : .twsk_prot = &tcp6_timewait_sock_ops,
1938 : : .rsk_prot = &tcp6_request_sock_ops,
1939 : : .h.hashinfo = &tcp_hashinfo,
1940 : : .no_autobind = true,
1941 : : #ifdef CONFIG_COMPAT
1942 : : .compat_setsockopt = compat_tcp_setsockopt,
1943 : : .compat_getsockopt = compat_tcp_getsockopt,
1944 : : #endif
1945 : : #ifdef CONFIG_MEMCG_KMEM
1946 : : .proto_cgroup = tcp_proto_cgroup,
1947 : : #endif
1948 : : .clear_sk = tcp_v6_clear_sk,
1949 : : };
1950 : :
1951 : : static const struct inet6_protocol tcpv6_protocol = {
1952 : : .early_demux = tcp_v6_early_demux,
1953 : : .handler = tcp_v6_rcv,
1954 : : .err_handler = tcp_v6_err,
1955 : : .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1956 : : };
1957 : :
1958 : : static struct inet_protosw tcpv6_protosw = {
1959 : : .type = SOCK_STREAM,
1960 : : .protocol = IPPROTO_TCP,
1961 : : .prot = &tcpv6_prot,
1962 : : .ops = &inet6_stream_ops,
1963 : : .no_check = 0,
1964 : : .flags = INET_PROTOSW_PERMANENT |
1965 : : INET_PROTOSW_ICSK,
1966 : : };
1967 : :
1968 : 0 : static int __net_init tcpv6_net_init(struct net *net)
1969 : : {
1970 : 0 : return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
1971 : : SOCK_RAW, IPPROTO_TCP, net);
1972 : : }
1973 : :
1974 : 0 : static void __net_exit tcpv6_net_exit(struct net *net)
1975 : : {
1976 : 0 : inet_ctl_sock_destroy(net->ipv6.tcp_sk);
1977 : 0 : }
1978 : :
1979 : 0 : static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
1980 : : {
1981 : 0 : inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
1982 : 0 : }
1983 : :
1984 : : static struct pernet_operations tcpv6_net_ops = {
1985 : : .init = tcpv6_net_init,
1986 : : .exit = tcpv6_net_exit,
1987 : : .exit_batch = tcpv6_net_exit_batch,
1988 : : };
1989 : :
1990 : 0 : int __init tcpv6_init(void)
1991 : : {
1992 : : int ret;
1993 : :
1994 : 0 : ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP);
1995 [ # # ]: 0 : if (ret)
1996 : : goto out;
1997 : :
1998 : : /* register inet6 protocol */
1999 : 0 : ret = inet6_register_protosw(&tcpv6_protosw);
2000 [ # # ]: 0 : if (ret)
2001 : : goto out_tcpv6_protocol;
2002 : :
2003 : 0 : ret = register_pernet_subsys(&tcpv6_net_ops);
2004 [ # # ]: 0 : if (ret)
2005 : : goto out_tcpv6_protosw;
2006 : : out:
2007 : 0 : return ret;
2008 : :
2009 : : out_tcpv6_protosw:
2010 : 0 : inet6_unregister_protosw(&tcpv6_protosw);
2011 : : out_tcpv6_protocol:
2012 : 0 : inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2013 : 0 : goto out;
2014 : : }
2015 : :
2016 : 0 : void tcpv6_exit(void)
2017 : : {
2018 : 0 : unregister_pernet_subsys(&tcpv6_net_ops);
2019 : 0 : inet6_unregister_protosw(&tcpv6_protosw);
2020 : 0 : inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2021 : 0 : }
|