diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-08-06 11:57:53 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:16:21 -0400 |
commit | 8f9d5b1a2e717fb9e0c4d2c60a224ecce905bd23 (patch) | |
tree | b72df915b34688c3b20b7b622b1eb738852259f6 /net/sunrpc | |
parent | 68e220bd5c9fc52d8029275cd42e08f573ce3600 (diff) |
SUNRPC: Add IPv6 address support to net/sunrpc/xprtsock.c
Finalize support for setting up RPC client transports to remote RPC
services addressed via IPv6.
Based on work done by Gilles Quillard at Bull Open Source.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/xprtsock.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index cc4db1763aa4..d9e65765f6c4 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -13,6 +13,9 @@ | |||
13 | * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no> | 13 | * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no> |
14 | * | 14 | * |
15 | * IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com> | 15 | * IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com> |
16 | * | ||
17 | * IPv6 support contributed by Gilles Quillard, Bull Open Source, 2005. | ||
18 | * <gilles.quillard@bull.net> | ||
16 | */ | 19 | */ |
17 | 20 | ||
18 | #include <linux/types.h> | 21 | #include <linux/types.h> |
@@ -1780,6 +1783,7 @@ static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned | |||
1780 | */ | 1783 | */ |
1781 | struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) | 1784 | struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) |
1782 | { | 1785 | { |
1786 | struct sockaddr *addr = args->dstaddr; | ||
1783 | struct rpc_xprt *xprt; | 1787 | struct rpc_xprt *xprt; |
1784 | struct sock_xprt *transport; | 1788 | struct sock_xprt *transport; |
1785 | 1789 | ||
@@ -1788,15 +1792,11 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) | |||
1788 | return xprt; | 1792 | return xprt; |
1789 | transport = container_of(xprt, struct sock_xprt, xprt); | 1793 | transport = container_of(xprt, struct sock_xprt, xprt); |
1790 | 1794 | ||
1791 | if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0) | ||
1792 | xprt_set_bound(xprt); | ||
1793 | |||
1794 | xprt->prot = IPPROTO_UDP; | 1795 | xprt->prot = IPPROTO_UDP; |
1795 | xprt->tsh_size = 0; | 1796 | xprt->tsh_size = 0; |
1796 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1797 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
1797 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1798 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
1798 | 1799 | ||
1799 | INIT_DELAYED_WORK(&transport->connect_worker, xs_udp_connect_worker4); | ||
1800 | xprt->bind_timeout = XS_BIND_TO; | 1800 | xprt->bind_timeout = XS_BIND_TO; |
1801 | xprt->connect_timeout = XS_UDP_CONN_TO; | 1801 | xprt->connect_timeout = XS_UDP_CONN_TO; |
1802 | xprt->reestablish_timeout = XS_UDP_REEST_TO; | 1802 | xprt->reestablish_timeout = XS_UDP_REEST_TO; |
@@ -1809,7 +1809,28 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) | |||
1809 | else | 1809 | else |
1810 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | 1810 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); |
1811 | 1811 | ||
1812 | xs_format_ipv4_peer_addresses(xprt); | 1812 | switch (addr->sa_family) { |
1813 | case AF_INET: | ||
1814 | if (((struct sockaddr_in *)addr)->sin_port != htons(0)) | ||
1815 | xprt_set_bound(xprt); | ||
1816 | |||
1817 | INIT_DELAYED_WORK(&transport->connect_worker, | ||
1818 | xs_udp_connect_worker4); | ||
1819 | xs_format_ipv4_peer_addresses(xprt); | ||
1820 | break; | ||
1821 | case AF_INET6: | ||
1822 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | ||
1823 | xprt_set_bound(xprt); | ||
1824 | |||
1825 | INIT_DELAYED_WORK(&transport->connect_worker, | ||
1826 | xs_udp_connect_worker6); | ||
1827 | xs_format_ipv6_peer_addresses(xprt); | ||
1828 | break; | ||
1829 | default: | ||
1830 | kfree(xprt); | ||
1831 | return ERR_PTR(-EAFNOSUPPORT); | ||
1832 | } | ||
1833 | |||
1813 | dprintk("RPC: set up transport to address %s\n", | 1834 | dprintk("RPC: set up transport to address %s\n", |
1814 | xprt->address_strings[RPC_DISPLAY_ALL]); | 1835 | xprt->address_strings[RPC_DISPLAY_ALL]); |
1815 | 1836 | ||
@@ -1823,6 +1844,7 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) | |||
1823 | */ | 1844 | */ |
1824 | struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args) | 1845 | struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args) |
1825 | { | 1846 | { |
1847 | struct sockaddr *addr = args->dstaddr; | ||
1826 | struct rpc_xprt *xprt; | 1848 | struct rpc_xprt *xprt; |
1827 | struct sock_xprt *transport; | 1849 | struct sock_xprt *transport; |
1828 | 1850 | ||
@@ -1831,14 +1853,10 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args) | |||
1831 | return xprt; | 1853 | return xprt; |
1832 | transport = container_of(xprt, struct sock_xprt, xprt); | 1854 | transport = container_of(xprt, struct sock_xprt, xprt); |
1833 | 1855 | ||
1834 | if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0) | ||
1835 | xprt_set_bound(xprt); | ||
1836 | |||
1837 | xprt->prot = IPPROTO_TCP; | 1856 | xprt->prot = IPPROTO_TCP; |
1838 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1857 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
1839 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1858 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
1840 | 1859 | ||
1841 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); | ||
1842 | xprt->bind_timeout = XS_BIND_TO; | 1860 | xprt->bind_timeout = XS_BIND_TO; |
1843 | xprt->connect_timeout = XS_TCP_CONN_TO; | 1861 | xprt->connect_timeout = XS_TCP_CONN_TO; |
1844 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | 1862 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; |
@@ -1851,7 +1869,26 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args) | |||
1851 | else | 1869 | else |
1852 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | 1870 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); |
1853 | 1871 | ||
1854 | xs_format_ipv4_peer_addresses(xprt); | 1872 | switch (addr->sa_family) { |
1873 | case AF_INET: | ||
1874 | if (((struct sockaddr_in *)addr)->sin_port != htons(0)) | ||
1875 | xprt_set_bound(xprt); | ||
1876 | |||
1877 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); | ||
1878 | xs_format_ipv4_peer_addresses(xprt); | ||
1879 | break; | ||
1880 | case AF_INET6: | ||
1881 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | ||
1882 | xprt_set_bound(xprt); | ||
1883 | |||
1884 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); | ||
1885 | xs_format_ipv6_peer_addresses(xprt); | ||
1886 | break; | ||
1887 | default: | ||
1888 | kfree(xprt); | ||
1889 | return ERR_PTR(-EAFNOSUPPORT); | ||
1890 | } | ||
1891 | |||
1855 | dprintk("RPC: set up transport to address %s\n", | 1892 | dprintk("RPC: set up transport to address %s\n", |
1856 | xprt->address_strings[RPC_DISPLAY_ALL]); | 1893 | xprt->address_strings[RPC_DISPLAY_ALL]); |
1857 | 1894 | ||