tcp_ipv6.c (1cbc99dfe5d7d686fd022647f4e489b5eb8e9068) | tcp_ipv6.c (90bbcc608369a1b46089b0f5aa22b8ea31ffa12e) |
---|---|
1/* 2 * TCP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on: --- 220 unchanged lines hidden (view full) --- 229 fl6.flowi6_proto = IPPROTO_TCP; 230 fl6.daddr = sk->sk_v6_daddr; 231 fl6.saddr = saddr ? *saddr : np->saddr; 232 fl6.flowi6_oif = sk->sk_bound_dev_if; 233 fl6.flowi6_mark = sk->sk_mark; 234 fl6.fl6_dport = usin->sin6_port; 235 fl6.fl6_sport = inet->inet_sport; 236 | 1/* 2 * TCP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on: --- 220 unchanged lines hidden (view full) --- 229 fl6.flowi6_proto = IPPROTO_TCP; 230 fl6.daddr = sk->sk_v6_daddr; 231 fl6.saddr = saddr ? *saddr : np->saddr; 232 fl6.flowi6_oif = sk->sk_bound_dev_if; 233 fl6.flowi6_mark = sk->sk_mark; 234 fl6.fl6_dport = usin->sin6_port; 235 fl6.fl6_sport = inet->inet_sport; 236 |
237 opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); | 237 opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk)); |
238 final_p = fl6_update_dst(&fl6, opt, &final); 239 240 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 241 242 dst = ip6_dst_lookup_flow(sk, &fl6, final_p); 243 if (IS_ERR(dst)) { 244 err = PTR_ERR(dst); 245 goto failure; --- 188 unchanged lines hidden (view full) --- 434 sock_put(sk); 435} 436 437 438static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, 439 struct flowi *fl, 440 struct request_sock *req, 441 struct tcp_fastopen_cookie *foc, | 238 final_p = fl6_update_dst(&fl6, opt, &final); 239 240 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 241 242 dst = ip6_dst_lookup_flow(sk, &fl6, final_p); 243 if (IS_ERR(dst)) { 244 err = PTR_ERR(dst); 245 goto failure; --- 188 unchanged lines hidden (view full) --- 434 sock_put(sk); 435} 436 437 438static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, 439 struct flowi *fl, 440 struct request_sock *req, 441 struct tcp_fastopen_cookie *foc, |
442 bool attach_req) | 442 enum tcp_synack_type synack_type) |
443{ 444 struct inet_request_sock *ireq = inet_rsk(req); 445 struct ipv6_pinfo *np = inet6_sk(sk); 446 struct flowi6 *fl6 = &fl->u.ip6; 447 struct sk_buff *skb; 448 int err = -ENOMEM; 449 450 /* First, grab a route. */ 451 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req, 452 IPPROTO_TCP)) == NULL) 453 goto done; 454 | 443{ 444 struct inet_request_sock *ireq = inet_rsk(req); 445 struct ipv6_pinfo *np = inet6_sk(sk); 446 struct flowi6 *fl6 = &fl->u.ip6; 447 struct sk_buff *skb; 448 int err = -ENOMEM; 449 450 /* First, grab a route. */ 451 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req, 452 IPPROTO_TCP)) == NULL) 453 goto done; 454 |
455 skb = tcp_make_synack(sk, dst, req, foc, attach_req); | 455 skb = tcp_make_synack(sk, dst, req, foc, synack_type); |
456 457 if (skb) { 458 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 459 &ireq->ir_v6_rmt_addr); 460 461 fl6->daddr = ireq->ir_v6_rmt_addr; 462 if (np->repflow && ireq->pktopts) 463 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); --- 356 unchanged lines hidden (view full) --- 820 /* Pass a socket to ip6_dst_lookup either it is for RST 821 * Underlying function will use this to retrieve the network 822 * namespace 823 */ 824 dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); 825 if (!IS_ERR(dst)) { 826 skb_dst_set(buff, dst); 827 ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass); | 456 457 if (skb) { 458 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 459 &ireq->ir_v6_rmt_addr); 460 461 fl6->daddr = ireq->ir_v6_rmt_addr; 462 if (np->repflow && ireq->pktopts) 463 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); --- 356 unchanged lines hidden (view full) --- 820 /* Pass a socket to ip6_dst_lookup either it is for RST 821 * Underlying function will use this to retrieve the network 822 * namespace 823 */ 824 dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); 825 if (!IS_ERR(dst)) { 826 skb_dst_set(buff, dst); 827 ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass); |
828 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 828 __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); |
829 if (rst) | 829 if (rst) |
830 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | 830 __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); |
831 return; 832 } 833 834 kfree_skb(buff); 835} 836 837static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) 838{ --- 14 unchanged lines hidden (view full) --- 853 854 /* If sk not NULL, it means we did a successful lookup and incoming 855 * route had to be correct. prequeue might have dropped our dst. 856 */ 857 if (!sk && !ipv6_unicast_destination(skb)) 858 return; 859 860#ifdef CONFIG_TCP_MD5SIG | 831 return; 832 } 833 834 kfree_skb(buff); 835} 836 837static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) 838{ --- 14 unchanged lines hidden (view full) --- 853 854 /* If sk not NULL, it means we did a successful lookup and incoming 855 * route had to be correct. prequeue might have dropped our dst. 856 */ 857 if (!sk && !ipv6_unicast_destination(skb)) 858 return; 859 860#ifdef CONFIG_TCP_MD5SIG |
861 rcu_read_lock(); |
|
861 hash_location = tcp_parse_md5sig_option(th); 862 if (sk && sk_fullsock(sk)) { 863 key = tcp_v6_md5_do_lookup(sk, &ipv6h->saddr); 864 } else if (hash_location) { 865 /* 866 * active side is lost. Try to find listening socket through 867 * source port, and then find md5 key through listening socket. 868 * we are not loose security here: 869 * Incoming packet is checked with md5 hash with finding key, 870 * no RST generated if md5 hash doesn't match. 871 */ 872 sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), 873 &tcp_hashinfo, NULL, 0, 874 &ipv6h->saddr, 875 th->source, &ipv6h->daddr, 876 ntohs(th->source), tcp_v6_iif(skb)); 877 if (!sk1) | 862 hash_location = tcp_parse_md5sig_option(th); 863 if (sk && sk_fullsock(sk)) { 864 key = tcp_v6_md5_do_lookup(sk, &ipv6h->saddr); 865 } else if (hash_location) { 866 /* 867 * active side is lost. Try to find listening socket through 868 * source port, and then find md5 key through listening socket. 869 * we are not loose security here: 870 * Incoming packet is checked with md5 hash with finding key, 871 * no RST generated if md5 hash doesn't match. 872 */ 873 sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), 874 &tcp_hashinfo, NULL, 0, 875 &ipv6h->saddr, 876 th->source, &ipv6h->daddr, 877 ntohs(th->source), tcp_v6_iif(skb)); 878 if (!sk1) |
878 return; | 879 goto out; |
879 | 880 |
880 rcu_read_lock(); | |
881 key = tcp_v6_md5_do_lookup(sk1, &ipv6h->saddr); 882 if (!key) | 881 key = tcp_v6_md5_do_lookup(sk1, &ipv6h->saddr); 882 if (!key) |
883 goto release_sk1; | 883 goto out; |
884 885 genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, skb); 886 if (genhash || memcmp(hash_location, newhash, 16) != 0) | 884 885 genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, skb); 886 if (genhash || memcmp(hash_location, newhash, 16) != 0) |
887 goto release_sk1; | 887 goto out; |
888 } 889#endif 890 891 if (th->ack) 892 seq = ntohl(th->ack_seq); 893 else 894 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - 895 (th->doff << 2); 896 897 oif = sk ? sk->sk_bound_dev_if : 0; 898 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); 899 900#ifdef CONFIG_TCP_MD5SIG | 888 } 889#endif 890 891 if (th->ack) 892 seq = ntohl(th->ack_seq); 893 else 894 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - 895 (th->doff << 2); 896 897 oif = sk ? sk->sk_bound_dev_if : 0; 898 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); 899 900#ifdef CONFIG_TCP_MD5SIG |
901release_sk1: 902 if (sk1) { 903 rcu_read_unlock(); 904 sock_put(sk1); 905 } | 901out: 902 rcu_read_unlock(); |
906#endif 907} 908 909static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, 910 u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, 911 struct tcp_md5sig_key *key, u8 tclass, 912 u32 label) 913{ --- 48 unchanged lines hidden (view full) --- 962 963 if (!ipv6_unicast_destination(skb)) 964 goto drop; 965 966 return tcp_conn_request(&tcp6_request_sock_ops, 967 &tcp_request_sock_ipv6_ops, sk, skb); 968 969drop: | 903#endif 904} 905 906static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, 907 u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, 908 struct tcp_md5sig_key *key, u8 tclass, 909 u32 label) 910{ --- 48 unchanged lines hidden (view full) --- 959 960 if (!ipv6_unicast_destination(skb)) 961 goto drop; 962 963 return tcp_conn_request(&tcp6_request_sock_ops, 964 &tcp_request_sock_ipv6_ops, sk, skb); 965 966drop: |
970 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | 967 tcp_listendrop(sk); |
971 return 0; /* don't send reset */ 972} 973 974static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, 975 struct request_sock *req, 976 struct dst_entry *dst, 977 struct request_sock *req_unhash, 978 bool *own_req) --- 188 unchanged lines hidden (view full) --- 1167 1168 return newsk; 1169 1170out_overflow: 1171 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); 1172out_nonewsk: 1173 dst_release(dst); 1174out: | 968 return 0; /* don't send reset */ 969} 970 971static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, 972 struct request_sock *req, 973 struct dst_entry *dst, 974 struct request_sock *req_unhash, 975 bool *own_req) --- 188 unchanged lines hidden (view full) --- 1164 1165 return newsk; 1166 1167out_overflow: 1168 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); 1169out_nonewsk: 1170 dst_release(dst); 1171out: |
1175 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | 1172 tcp_listendrop(sk); |
1176 return NULL; 1177} 1178 1179/* The socket must have it's spinlock held when we get 1180 * here, unless it is a TCP_LISTEN socket. 1181 * 1182 * We have a potential double-lock case here, so even when 1183 * doing backlog processing we use the BH locking scheme. --- 90 unchanged lines hidden (view full) --- 1274reset: 1275 tcp_v6_send_reset(sk, skb); 1276discard: 1277 if (opt_skb) 1278 __kfree_skb(opt_skb); 1279 kfree_skb(skb); 1280 return 0; 1281csum_err: | 1173 return NULL; 1174} 1175 1176/* The socket must have it's spinlock held when we get 1177 * here, unless it is a TCP_LISTEN socket. 1178 * 1179 * We have a potential double-lock case here, so even when 1180 * doing backlog processing we use the BH locking scheme. --- 90 unchanged lines hidden (view full) --- 1271reset: 1272 tcp_v6_send_reset(sk, skb); 1273discard: 1274 if (opt_skb) 1275 __kfree_skb(opt_skb); 1276 kfree_skb(skb); 1277 return 0; 1278csum_err: |
1282 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS); 1283 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); | 1279 __TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS); 1280 __TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS); |
1284 goto discard; 1285 1286 1287ipv6_pktoptions: 1288 /* Do you ask, what is it? 1289 1290 1. skb was enqueued by tcp. 1291 2. skb is added to tail of read queue, rather than out of order. --- 54 unchanged lines hidden (view full) --- 1346 memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, 1347 sizeof(struct inet6_skb_parm)); 1348} 1349 1350static int tcp_v6_rcv(struct sk_buff *skb) 1351{ 1352 const struct tcphdr *th; 1353 const struct ipv6hdr *hdr; | 1281 goto discard; 1282 1283 1284ipv6_pktoptions: 1285 /* Do you ask, what is it? 1286 1287 1. skb was enqueued by tcp. 1288 2. skb is added to tail of read queue, rather than out of order. --- 54 unchanged lines hidden (view full) --- 1343 memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, 1344 sizeof(struct inet6_skb_parm)); 1345} 1346 1347static int tcp_v6_rcv(struct sk_buff *skb) 1348{ 1349 const struct tcphdr *th; 1350 const struct ipv6hdr *hdr; |
1351 bool refcounted; |
|
1354 struct sock *sk; 1355 int ret; 1356 struct net *net = dev_net(skb->dev); 1357 1358 if (skb->pkt_type != PACKET_HOST) 1359 goto discard_it; 1360 1361 /* 1362 * Count it even if it's bad. 1363 */ | 1352 struct sock *sk; 1353 int ret; 1354 struct net *net = dev_net(skb->dev); 1355 1356 if (skb->pkt_type != PACKET_HOST) 1357 goto discard_it; 1358 1359 /* 1360 * Count it even if it's bad. 1361 */ |
1364 TCP_INC_STATS_BH(net, TCP_MIB_INSEGS); | 1362 __TCP_INC_STATS(net, TCP_MIB_INSEGS); |
1365 1366 if (!pskb_may_pull(skb, sizeof(struct tcphdr))) 1367 goto discard_it; 1368 1369 th = tcp_hdr(skb); 1370 1371 if (th->doff < sizeof(struct tcphdr)/4) 1372 goto bad_packet; 1373 if (!pskb_may_pull(skb, th->doff*4)) 1374 goto discard_it; 1375 1376 if (skb_checksum_init(skb, IPPROTO_TCP, ip6_compute_pseudo)) 1377 goto csum_error; 1378 1379 th = tcp_hdr(skb); 1380 hdr = ipv6_hdr(skb); 1381 1382lookup: 1383 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), | 1363 1364 if (!pskb_may_pull(skb, sizeof(struct tcphdr))) 1365 goto discard_it; 1366 1367 th = tcp_hdr(skb); 1368 1369 if (th->doff < sizeof(struct tcphdr)/4) 1370 goto bad_packet; 1371 if (!pskb_may_pull(skb, th->doff*4)) 1372 goto discard_it; 1373 1374 if (skb_checksum_init(skb, IPPROTO_TCP, ip6_compute_pseudo)) 1375 goto csum_error; 1376 1377 th = tcp_hdr(skb); 1378 hdr = ipv6_hdr(skb); 1379 1380lookup: 1381 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), |
1384 th->source, th->dest, inet6_iif(skb)); | 1382 th->source, th->dest, inet6_iif(skb), 1383 &refcounted); |
1385 if (!sk) 1386 goto no_tcp_socket; 1387 1388process: 1389 if (sk->sk_state == TCP_TIME_WAIT) 1390 goto do_time_wait; 1391 1392 if (sk->sk_state == TCP_NEW_SYN_RECV) { --- 6 unchanged lines hidden (view full) --- 1399 reqsk_put(req); 1400 goto discard_it; 1401 } 1402 if (unlikely(sk->sk_state != TCP_LISTEN)) { 1403 inet_csk_reqsk_queue_drop_and_put(sk, req); 1404 goto lookup; 1405 } 1406 sock_hold(sk); | 1384 if (!sk) 1385 goto no_tcp_socket; 1386 1387process: 1388 if (sk->sk_state == TCP_TIME_WAIT) 1389 goto do_time_wait; 1390 1391 if (sk->sk_state == TCP_NEW_SYN_RECV) { --- 6 unchanged lines hidden (view full) --- 1398 reqsk_put(req); 1399 goto discard_it; 1400 } 1401 if (unlikely(sk->sk_state != TCP_LISTEN)) { 1402 inet_csk_reqsk_queue_drop_and_put(sk, req); 1403 goto lookup; 1404 } 1405 sock_hold(sk); |
1406 refcounted = true; |
|
1407 nsk = tcp_check_req(sk, skb, req, false); 1408 if (!nsk) { 1409 reqsk_put(req); 1410 goto discard_and_relse; 1411 } 1412 if (nsk == sk) { 1413 reqsk_put(req); 1414 tcp_v6_restore_cb(skb); --- 40 unchanged lines hidden (view full) --- 1455 sk->sk_rcvbuf + sk->sk_sndbuf))) { 1456 bh_unlock_sock(sk); 1457 NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); 1458 goto discard_and_relse; 1459 } 1460 bh_unlock_sock(sk); 1461 1462put_and_return: | 1407 nsk = tcp_check_req(sk, skb, req, false); 1408 if (!nsk) { 1409 reqsk_put(req); 1410 goto discard_and_relse; 1411 } 1412 if (nsk == sk) { 1413 reqsk_put(req); 1414 tcp_v6_restore_cb(skb); --- 40 unchanged lines hidden (view full) --- 1455 sk->sk_rcvbuf + sk->sk_sndbuf))) { 1456 bh_unlock_sock(sk); 1457 NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); 1458 goto discard_and_relse; 1459 } 1460 bh_unlock_sock(sk); 1461 1462put_and_return: |
1463 sock_put(sk); | 1463 if (refcounted) 1464 sock_put(sk); |
1464 return ret ? -1 : 0; 1465 1466no_tcp_socket: 1467 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 1468 goto discard_it; 1469 1470 tcp_v6_fill_cb(skb, hdr, th); 1471 1472 if (tcp_checksum_complete(skb)) { 1473csum_error: | 1465 return ret ? -1 : 0; 1466 1467no_tcp_socket: 1468 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 1469 goto discard_it; 1470 1471 tcp_v6_fill_cb(skb, hdr, th); 1472 1473 if (tcp_checksum_complete(skb)) { 1474csum_error: |
1474 TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | 1475 __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); |
1475bad_packet: | 1476bad_packet: |
1476 TCP_INC_STATS_BH(net, TCP_MIB_INERRS); | 1477 __TCP_INC_STATS(net, TCP_MIB_INERRS); |
1477 } else { 1478 tcp_v6_send_reset(NULL, skb); 1479 } 1480 1481discard_it: 1482 kfree_skb(skb); 1483 return 0; 1484 1485discard_and_relse: | 1478 } else { 1479 tcp_v6_send_reset(NULL, skb); 1480 } 1481 1482discard_it: 1483 kfree_skb(skb); 1484 return 0; 1485 1486discard_and_relse: |
1486 sock_put(sk); | 1487 sk_drops_add(sk, skb); 1488 if (refcounted) 1489 sock_put(sk); |
1487 goto discard_it; 1488 1489do_time_wait: 1490 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 1491 inet_twsk_put(inet_twsk(sk)); 1492 goto discard_it; 1493 } 1494 --- 14 unchanged lines hidden (view full) --- 1509 &ipv6_hdr(skb)->saddr, th->source, 1510 &ipv6_hdr(skb)->daddr, 1511 ntohs(th->dest), tcp_v6_iif(skb)); 1512 if (sk2) { 1513 struct inet_timewait_sock *tw = inet_twsk(sk); 1514 inet_twsk_deschedule_put(tw); 1515 sk = sk2; 1516 tcp_v6_restore_cb(skb); | 1490 goto discard_it; 1491 1492do_time_wait: 1493 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 1494 inet_twsk_put(inet_twsk(sk)); 1495 goto discard_it; 1496 } 1497 --- 14 unchanged lines hidden (view full) --- 1512 &ipv6_hdr(skb)->saddr, th->source, 1513 &ipv6_hdr(skb)->daddr, 1514 ntohs(th->dest), tcp_v6_iif(skb)); 1515 if (sk2) { 1516 struct inet_timewait_sock *tw = inet_twsk(sk); 1517 inet_twsk_deschedule_put(tw); 1518 sk = sk2; 1519 tcp_v6_restore_cb(skb); |
1520 refcounted = false; |
|
1517 goto process; 1518 } 1519 /* Fall through to ACK */ 1520 } 1521 case TCP_TW_ACK: 1522 tcp_v6_timewait_ack(sk, skb); 1523 break; 1524 case TCP_TW_RST: --- 446 unchanged lines hidden --- | 1521 goto process; 1522 } 1523 /* Fall through to ACK */ 1524 } 1525 case TCP_TW_ACK: 1526 tcp_v6_timewait_ack(sk, skb); 1527 break; 1528 case TCP_TW_RST: --- 446 unchanged lines hidden --- |