aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c153
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
74static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); 74static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
75static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
76 75
77static struct inet_connection_sock_af_ops ipv6_mapped; 76static struct inet_connection_sock_af_ops ipv6_mapped;
78static struct inet_connection_sock_af_ops ipv6_specific; 77static struct inet_connection_sock_af_ops ipv6_specific;
79 78
80int 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
101static int tcp_v6_get_port(struct sock *sk, unsigned short snum) 79static 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
1503static 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
1553static 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
1610static 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
1626static int tcp_v6_remember_stamp(struct sock *sk) 1481static 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
1632static struct inet_connection_sock_af_ops ipv6_specific = { 1487static 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