diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 153 |
1 files changed, 4 insertions, 149 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 8ce8a1359d2b..2f932ce72610 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -72,32 +72,10 @@ static void tcp_v6_send_check(struct sock *sk, int len, | |||
72 | struct sk_buff *skb); | 72 | struct sk_buff *skb); |
73 | 73 | ||
74 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 74 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
75 | static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok); | ||
76 | 75 | ||
77 | static struct inet_connection_sock_af_ops ipv6_mapped; | 76 | static struct inet_connection_sock_af_ops ipv6_mapped; |
78 | static struct inet_connection_sock_af_ops ipv6_specific; | 77 | static struct inet_connection_sock_af_ops ipv6_specific; |
79 | 78 | ||
80 | int inet6_csk_bind_conflict(const struct sock *sk, | ||
81 | const struct inet_bind_bucket *tb) | ||
82 | { | ||
83 | const struct sock *sk2; | ||
84 | const struct hlist_node *node; | ||
85 | |||
86 | /* We must walk the whole port owner list in this case. -DaveM */ | ||
87 | sk_for_each_bound(sk2, node, &tb->owners) { | ||
88 | if (sk != sk2 && | ||
89 | (!sk->sk_bound_dev_if || | ||
90 | !sk2->sk_bound_dev_if || | ||
91 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && | ||
92 | (!sk->sk_reuse || !sk2->sk_reuse || | ||
93 | sk2->sk_state == TCP_LISTEN) && | ||
94 | ipv6_rcv_saddr_equal(sk, sk2)) | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | return node != NULL; | ||
99 | } | ||
100 | |||
101 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | 79 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) |
102 | { | 80 | { |
103 | return inet_csk_get_port(&tcp_hashinfo, sk, snum, | 81 | return inet_csk_get_port(&tcp_hashinfo, sk, snum, |
@@ -1500,129 +1478,6 @@ do_time_wait: | |||
1500 | goto discard_it; | 1478 | goto discard_it; |
1501 | } | 1479 | } |
1502 | 1480 | ||
1503 | static int tcp_v6_rebuild_header(struct sock *sk) | ||
1504 | { | ||
1505 | int err; | ||
1506 | struct dst_entry *dst; | ||
1507 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1508 | |||
1509 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
1510 | |||
1511 | if (dst == NULL) { | ||
1512 | struct inet_sock *inet = inet_sk(sk); | ||
1513 | struct in6_addr *final_p = NULL, final; | ||
1514 | struct flowi fl; | ||
1515 | |||
1516 | memset(&fl, 0, sizeof(fl)); | ||
1517 | fl.proto = IPPROTO_TCP; | ||
1518 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1519 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
1520 | fl.fl6_flowlabel = np->flow_label; | ||
1521 | fl.oif = sk->sk_bound_dev_if; | ||
1522 | fl.fl_ip_dport = inet->dport; | ||
1523 | fl.fl_ip_sport = inet->sport; | ||
1524 | |||
1525 | if (np->opt && np->opt->srcrt) { | ||
1526 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
1527 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
1528 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
1529 | final_p = &final; | ||
1530 | } | ||
1531 | |||
1532 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
1533 | if (err) { | ||
1534 | sk->sk_route_caps = 0; | ||
1535 | return err; | ||
1536 | } | ||
1537 | if (final_p) | ||
1538 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
1539 | |||
1540 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
1541 | sk->sk_err_soft = -err; | ||
1542 | return err; | ||
1543 | } | ||
1544 | |||
1545 | ip6_dst_store(sk, dst, NULL); | ||
1546 | sk->sk_route_caps = dst->dev->features & | ||
1547 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1548 | } | ||
1549 | |||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) | ||
1554 | { | ||
1555 | struct sock *sk = skb->sk; | ||
1556 | struct inet_sock *inet = inet_sk(sk); | ||
1557 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1558 | struct flowi fl; | ||
1559 | struct dst_entry *dst; | ||
1560 | struct in6_addr *final_p = NULL, final; | ||
1561 | |||
1562 | memset(&fl, 0, sizeof(fl)); | ||
1563 | fl.proto = IPPROTO_TCP; | ||
1564 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1565 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
1566 | fl.fl6_flowlabel = np->flow_label; | ||
1567 | IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); | ||
1568 | fl.oif = sk->sk_bound_dev_if; | ||
1569 | fl.fl_ip_sport = inet->sport; | ||
1570 | fl.fl_ip_dport = inet->dport; | ||
1571 | |||
1572 | if (np->opt && np->opt->srcrt) { | ||
1573 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
1574 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
1575 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
1576 | final_p = &final; | ||
1577 | } | ||
1578 | |||
1579 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
1580 | |||
1581 | if (dst == NULL) { | ||
1582 | int err = ip6_dst_lookup(sk, &dst, &fl); | ||
1583 | |||
1584 | if (err) { | ||
1585 | sk->sk_err_soft = -err; | ||
1586 | return err; | ||
1587 | } | ||
1588 | |||
1589 | if (final_p) | ||
1590 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
1591 | |||
1592 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
1593 | sk->sk_route_caps = 0; | ||
1594 | return err; | ||
1595 | } | ||
1596 | |||
1597 | ip6_dst_store(sk, dst, NULL); | ||
1598 | sk->sk_route_caps = dst->dev->features & | ||
1599 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1600 | } | ||
1601 | |||
1602 | skb->dst = dst_clone(dst); | ||
1603 | |||
1604 | /* Restore final destination back after routing done */ | ||
1605 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1606 | |||
1607 | return ip6_xmit(sk, skb, &fl, np->opt, 0); | ||
1608 | } | ||
1609 | |||
1610 | static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | ||
1611 | { | ||
1612 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1613 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; | ||
1614 | |||
1615 | sin6->sin6_family = AF_INET6; | ||
1616 | ipv6_addr_copy(&sin6->sin6_addr, &np->daddr); | ||
1617 | sin6->sin6_port = inet_sk(sk)->dport; | ||
1618 | /* We do not store received flowlabel for TCP */ | ||
1619 | sin6->sin6_flowinfo = 0; | ||
1620 | sin6->sin6_scope_id = 0; | ||
1621 | if (sk->sk_bound_dev_if && | ||
1622 | ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | ||
1623 | sin6->sin6_scope_id = sk->sk_bound_dev_if; | ||
1624 | } | ||
1625 | |||
1626 | static int tcp_v6_remember_stamp(struct sock *sk) | 1481 | static int tcp_v6_remember_stamp(struct sock *sk) |
1627 | { | 1482 | { |
1628 | /* Alas, not yet... */ | 1483 | /* Alas, not yet... */ |
@@ -1630,9 +1485,9 @@ static int tcp_v6_remember_stamp(struct sock *sk) | |||
1630 | } | 1485 | } |
1631 | 1486 | ||
1632 | static struct inet_connection_sock_af_ops ipv6_specific = { | 1487 | static struct inet_connection_sock_af_ops ipv6_specific = { |
1633 | .queue_xmit = tcp_v6_xmit, | 1488 | .queue_xmit = inet6_csk_xmit, |
1634 | .send_check = tcp_v6_send_check, | 1489 | .send_check = tcp_v6_send_check, |
1635 | .rebuild_header = tcp_v6_rebuild_header, | 1490 | .rebuild_header = inet6_sk_rebuild_header, |
1636 | .conn_request = tcp_v6_conn_request, | 1491 | .conn_request = tcp_v6_conn_request, |
1637 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1492 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1638 | .remember_stamp = tcp_v6_remember_stamp, | 1493 | .remember_stamp = tcp_v6_remember_stamp, |
@@ -1640,7 +1495,7 @@ static struct inet_connection_sock_af_ops ipv6_specific = { | |||
1640 | 1495 | ||
1641 | .setsockopt = ipv6_setsockopt, | 1496 | .setsockopt = ipv6_setsockopt, |
1642 | .getsockopt = ipv6_getsockopt, | 1497 | .getsockopt = ipv6_getsockopt, |
1643 | .addr2sockaddr = v6_addr2sockaddr, | 1498 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1644 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1499 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1645 | }; | 1500 | }; |
1646 | 1501 | ||
@@ -1659,7 +1514,7 @@ static struct inet_connection_sock_af_ops ipv6_mapped = { | |||
1659 | 1514 | ||
1660 | .setsockopt = ipv6_setsockopt, | 1515 | .setsockopt = ipv6_setsockopt, |
1661 | .getsockopt = ipv6_getsockopt, | 1516 | .getsockopt = ipv6_getsockopt, |
1662 | .addr2sockaddr = v6_addr2sockaddr, | 1517 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1663 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1518 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1664 | }; | 1519 | }; |
1665 | 1520 | ||