tcp_ipv6.c (0ea8a56de21be24cb79abb03dee79aabcd60a316) | tcp_ipv6.c (634a63e73f059439bb44d1c26ba742ee6311957e) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * TCP over IPv6 4 * Linux INET6 implementation 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 * --- 444 unchanged lines hidden (view full) --- 453 } 454 455 456 /* Might be for an request_sock */ 457 switch (sk->sk_state) { 458 case TCP_SYN_SENT: 459 case TCP_SYN_RECV: 460 /* Only in fast or simultaneous open. If a fast open socket is | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * TCP over IPv6 4 * Linux INET6 implementation 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 * --- 444 unchanged lines hidden (view full) --- 453 } 454 455 456 /* Might be for an request_sock */ 457 switch (sk->sk_state) { 458 case TCP_SYN_SENT: 459 case TCP_SYN_RECV: 460 /* Only in fast or simultaneous open. If a fast open socket is |
461 * is already accepted it is treated as a connected one below. | 461 * already accepted it is treated as a connected one below. |
462 */ 463 if (fastopen && !fastopen->sk) 464 break; 465 466 ipv6_icmp_error(sk, skb, err, th->dest, ntohl(info), (u8 *)th); 467 468 if (!sock_owned_by_user(sk)) { 469 sk->sk_err = err; --- 26 unchanged lines hidden (view full) --- 496 return 0; 497} 498 499 500static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, 501 struct flowi *fl, 502 struct request_sock *req, 503 struct tcp_fastopen_cookie *foc, | 462 */ 463 if (fastopen && !fastopen->sk) 464 break; 465 466 ipv6_icmp_error(sk, skb, err, th->dest, ntohl(info), (u8 *)th); 467 468 if (!sock_owned_by_user(sk)) { 469 sk->sk_err = err; --- 26 unchanged lines hidden (view full) --- 496 return 0; 497} 498 499 500static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, 501 struct flowi *fl, 502 struct request_sock *req, 503 struct tcp_fastopen_cookie *foc, |
504 enum tcp_synack_type synack_type) | 504 enum tcp_synack_type synack_type, 505 struct sk_buff *syn_skb) |
505{ 506 struct inet_request_sock *ireq = inet_rsk(req); 507 struct ipv6_pinfo *np = tcp_inet6_sk(sk); 508 struct ipv6_txoptions *opt; 509 struct flowi6 *fl6 = &fl->u.ip6; 510 struct sk_buff *skb; 511 int err = -ENOMEM; | 506{ 507 struct inet_request_sock *ireq = inet_rsk(req); 508 struct ipv6_pinfo *np = tcp_inet6_sk(sk); 509 struct ipv6_txoptions *opt; 510 struct flowi6 *fl6 = &fl->u.ip6; 511 struct sk_buff *skb; 512 int err = -ENOMEM; |
513 u8 tclass; |
|
512 513 /* First, grab a route. */ 514 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req, 515 IPPROTO_TCP)) == NULL) 516 goto done; 517 | 514 515 /* First, grab a route. */ 516 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req, 517 IPPROTO_TCP)) == NULL) 518 goto done; 519 |
518 skb = tcp_make_synack(sk, dst, req, foc, synack_type); | 520 skb = tcp_make_synack(sk, dst, req, foc, synack_type, syn_skb); |
519 520 if (skb) { 521 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 522 &ireq->ir_v6_rmt_addr); 523 524 fl6->daddr = ireq->ir_v6_rmt_addr; 525 if (np->repflow && ireq->pktopts) 526 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); 527 528 rcu_read_lock(); 529 opt = ireq->ipv6_opt; | 521 522 if (skb) { 523 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 524 &ireq->ir_v6_rmt_addr); 525 526 fl6->daddr = ireq->ir_v6_rmt_addr; 527 if (np->repflow && ireq->pktopts) 528 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); 529 530 rcu_read_lock(); 531 opt = ireq->ipv6_opt; |
532 tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? 533 tcp_rsk(req)->syn_tos : np->tclass; |
|
530 if (!opt) 531 opt = rcu_dereference(np->opt); | 534 if (!opt) 535 opt = rcu_dereference(np->opt); |
532 err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, np->tclass, | 536 err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, 537 tclass & ~INET_ECN_MASK, |
533 sk->sk_priority); 534 rcu_read_unlock(); 535 err = net_xmit_eval(err); 536 } 537 538done: 539 return err; 540} --- 412 unchanged lines hidden (view full) --- 953 954 /* Pass a socket to ip6_dst_lookup either it is for RST 955 * Underlying function will use this to retrieve the network 956 * namespace 957 */ 958 dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); 959 if (!IS_ERR(dst)) { 960 skb_dst_set(buff, dst); | 538 sk->sk_priority); 539 rcu_read_unlock(); 540 err = net_xmit_eval(err); 541 } 542 543done: 544 return err; 545} --- 412 unchanged lines hidden (view full) --- 958 959 /* Pass a socket to ip6_dst_lookup either it is for RST 960 * Underlying function will use this to retrieve the network 961 * namespace 962 */ 963 dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); 964 if (!IS_ERR(dst)) { 965 skb_dst_set(buff, dst); |
961 ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass, 962 priority); | 966 ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, 967 tclass & ~INET_ECN_MASK, priority); |
963 TCP_INC_STATS(net, TCP_MIB_OUTSEGS); 964 if (rst) 965 TCP_INC_STATS(net, TCP_MIB_OUTRSTS); 966 return; 967 } 968 969 kfree_skb(buff); 970} --- 91 unchanged lines hidden (view full) --- 1062 label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); 1063 priority = inet_twsk(sk)->tw_priority; 1064 } 1065 } else { 1066 if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET) 1067 label = ip6_flowlabel(ipv6h); 1068 } 1069 | 968 TCP_INC_STATS(net, TCP_MIB_OUTSEGS); 969 if (rst) 970 TCP_INC_STATS(net, TCP_MIB_OUTRSTS); 971 return; 972 } 973 974 kfree_skb(buff); 975} --- 91 unchanged lines hidden (view full) --- 1067 label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); 1068 priority = inet_twsk(sk)->tw_priority; 1069 } 1070 } else { 1071 if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET) 1072 label = ip6_flowlabel(ipv6h); 1073 } 1074 |
1070 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 1071 label, priority); | 1075 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 1076 ipv6_get_dsfield(ipv6h), label, priority); |
1072 1073#ifdef CONFIG_TCP_MD5SIG 1074out: 1075 rcu_read_unlock(); 1076#endif 1077} 1078 1079static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, --- 36 unchanged lines hidden (view full) --- 1116 */ 1117 tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? 1118 tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, 1119 tcp_rsk(req)->rcv_nxt, 1120 req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, 1121 tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, 1122 req->ts_recent, sk->sk_bound_dev_if, 1123 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), | 1077 1078#ifdef CONFIG_TCP_MD5SIG 1079out: 1080 rcu_read_unlock(); 1081#endif 1082} 1083 1084static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, --- 36 unchanged lines hidden (view full) --- 1121 */ 1122 tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? 1123 tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, 1124 tcp_rsk(req)->rcv_nxt, 1125 req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, 1126 tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, 1127 req->ts_recent, sk->sk_bound_dev_if, 1128 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), |
1124 0, 0, sk->sk_priority); | 1129 ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority); |
1125} 1126 1127 1128static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) 1129{ 1130#ifdef CONFIG_SYN_COOKIES 1131 const struct tcphdr *th = tcp_hdr(skb); 1132 --- 171 unchanged lines hidden (view full) --- 1304 newnp->pktoptions = NULL; 1305 newnp->opt = NULL; 1306 newnp->mcast_oif = tcp_v6_iif(skb); 1307 newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; 1308 newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); 1309 if (np->repflow) 1310 newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb)); 1311 | 1130} 1131 1132 1133static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) 1134{ 1135#ifdef CONFIG_SYN_COOKIES 1136 const struct tcphdr *th = tcp_hdr(skb); 1137 --- 171 unchanged lines hidden (view full) --- 1309 newnp->pktoptions = NULL; 1310 newnp->opt = NULL; 1311 newnp->mcast_oif = tcp_v6_iif(skb); 1312 newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; 1313 newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); 1314 if (np->repflow) 1315 newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb)); 1316 |
1317 /* Set ToS of the new socket based upon the value of incoming SYN. */ 1318 if (sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) 1319 newnp->tclass = tcp_rsk(req)->syn_tos & ~INET_ECN_MASK; 1320 |
|
1312 /* Clone native IPv6 options from listening socket (if any) 1313 1314 Yes, keeping reference count would be much more clever, 1315 but we make one more one thing there: reattach optmem 1316 to newsk. 1317 */ 1318 opt = ireq->ipv6_opt; 1319 if (!opt) --- 882 unchanged lines hidden --- | 1321 /* Clone native IPv6 options from listening socket (if any) 1322 1323 Yes, keeping reference count would be much more clever, 1324 but we make one more one thing there: reattach optmem 1325 to newsk. 1326 */ 1327 opt = ireq->ipv6_opt; 1328 if (!opt) --- 882 unchanged lines hidden --- |