aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/host.c14
-rw-r--r--fs/lockd/mon.c44
-rw-r--r--fs/nfs/internal.h23
-rw-r--r--fs/nfs/mount_clnt.c79
-rw-r--r--fs/nfs/nfs4namespace.c8
-rw-r--r--fs/nfs/super.c247
-rw-r--r--fs/nfsd/nfsctl.c21
-rw-r--r--include/linux/sunrpc/clnt.h38
-rw-r--r--include/linux/sunrpc/msg_prot.h17
-rw-r--r--include/linux/sunrpc/xprt.h2
-rw-r--r--net/sunrpc/Makefile2
-rw-r--r--net/sunrpc/addr.c364
-rw-r--r--net/sunrpc/rpcb_clnt.c420
-rw-r--r--net/sunrpc/timer.c45
-rw-r--r--net/sunrpc/xprtrdma/transport.c48
-rw-r--r--net/sunrpc/xprtsock.c235
16 files changed, 1022 insertions, 585 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 99d737bd4325..7cb076ac6b45 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -87,18 +87,6 @@ static unsigned int nlm_hash_address(const struct sockaddr *sap)
87 return hash & (NLM_HOST_NRHASH - 1); 87 return hash & (NLM_HOST_NRHASH - 1);
88} 88}
89 89
90static void nlm_clear_port(struct sockaddr *sap)
91{
92 switch (sap->sa_family) {
93 case AF_INET:
94 ((struct sockaddr_in *)sap)->sin_port = 0;
95 break;
96 case AF_INET6:
97 ((struct sockaddr_in6 *)sap)->sin6_port = 0;
98 break;
99 }
100}
101
102/* 90/*
103 * Common host lookup routine for server & client 91 * Common host lookup routine for server & client
104 */ 92 */
@@ -177,7 +165,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
177 host->h_addrbuf = nsm->sm_addrbuf; 165 host->h_addrbuf = nsm->sm_addrbuf;
178 memcpy(nlm_addr(host), ni->sap, ni->salen); 166 memcpy(nlm_addr(host), ni->sap, ni->salen);
179 host->h_addrlen = ni->salen; 167 host->h_addrlen = ni->salen;
180 nlm_clear_port(nlm_addr(host)); 168 rpc_set_port(nlm_addr(host), 0);
181 memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); 169 memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len);
182 host->h_version = ni->version; 170 host->h_version = ni->version;
183 host->h_proto = ni->protocol; 171 host->h_proto = ni->protocol;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 7fce1b525849..30c933188dd7 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -61,43 +61,6 @@ static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm)
61 return (struct sockaddr *)&nsm->sm_addr; 61 return (struct sockaddr *)&nsm->sm_addr;
62} 62}
63 63
64static void nsm_display_ipv4_address(const struct sockaddr *sap, char *buf,
65 const size_t len)
66{
67 const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
68 snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
69}
70
71static void nsm_display_ipv6_address(const struct sockaddr *sap, char *buf,
72 const size_t len)
73{
74 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
75
76 if (ipv6_addr_v4mapped(&sin6->sin6_addr))
77 snprintf(buf, len, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
78 else if (sin6->sin6_scope_id != 0)
79 snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
80 sin6->sin6_scope_id);
81 else
82 snprintf(buf, len, "%pI6", &sin6->sin6_addr);
83}
84
85static void nsm_display_address(const struct sockaddr *sap,
86 char *buf, const size_t len)
87{
88 switch (sap->sa_family) {
89 case AF_INET:
90 nsm_display_ipv4_address(sap, buf, len);
91 break;
92 case AF_INET6:
93 nsm_display_ipv6_address(sap, buf, len);
94 break;
95 default:
96 snprintf(buf, len, "unsupported address family");
97 break;
98 }
99}
100
101static struct rpc_clnt *nsm_create(void) 64static struct rpc_clnt *nsm_create(void)
102{ 65{
103 struct sockaddr_in sin = { 66 struct sockaddr_in sin = {
@@ -307,8 +270,11 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
307 memcpy(nsm_addr(new), sap, salen); 270 memcpy(nsm_addr(new), sap, salen);
308 new->sm_addrlen = salen; 271 new->sm_addrlen = salen;
309 nsm_init_private(new); 272 nsm_init_private(new);
310 nsm_display_address((const struct sockaddr *)&new->sm_addr, 273
311 new->sm_addrbuf, sizeof(new->sm_addrbuf)); 274 if (rpc_ntop(nsm_addr(new), new->sm_addrbuf,
275 sizeof(new->sm_addrbuf)) == 0)
276 (void)snprintf(new->sm_addrbuf, sizeof(new->sm_addrbuf),
277 "unsupported address family");
312 memcpy(new->sm_name, hostname, hostname_len); 278 memcpy(new->sm_name, hostname, hostname_len);
313 new->sm_name[hostname_len] = '\0'; 279 new->sm_name[hostname_len] = '\0';
314 280
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e2ccb4a4398a..2e485677019c 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -102,6 +102,7 @@ struct nfs_mount_request {
102}; 102};
103 103
104extern int nfs_mount(struct nfs_mount_request *info); 104extern int nfs_mount(struct nfs_mount_request *info);
105extern void nfs_umount(const struct nfs_mount_request *info);
105 106
106/* client.c */ 107/* client.c */
107extern struct rpc_program nfs_program; 108extern struct rpc_program nfs_program;
@@ -213,7 +214,6 @@ void nfs_zap_acl_cache(struct inode *inode);
213extern int nfs_wait_bit_killable(void *word); 214extern int nfs_wait_bit_killable(void *word);
214 215
215/* super.c */ 216/* super.c */
216void nfs_parse_ip_address(char *, size_t, struct sockaddr *, size_t *);
217extern struct file_system_type nfs_xdev_fs_type; 217extern struct file_system_type nfs_xdev_fs_type;
218#ifdef CONFIG_NFS_V4 218#ifdef CONFIG_NFS_V4
219extern struct file_system_type nfs4_xdev_fs_type; 219extern struct file_system_type nfs4_xdev_fs_type;
@@ -374,24 +374,3 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
374 return ((unsigned long)len + (unsigned long)base + 374 return ((unsigned long)len + (unsigned long)base +
375 PAGE_SIZE - 1) >> PAGE_SHIFT; 375 PAGE_SIZE - 1) >> PAGE_SHIFT;
376} 376}
377
378#define IPV6_SCOPE_DELIMITER '%'
379
380/*
381 * Set the port number in an address. Be agnostic about the address
382 * family.
383 */
384static inline void nfs_set_port(struct sockaddr *sap, unsigned short port)
385{
386 struct sockaddr_in *ap = (struct sockaddr_in *)sap;
387 struct sockaddr_in6 *ap6 = (struct sockaddr_in6 *)sap;
388
389 switch (sap->sa_family) {
390 case AF_INET:
391 ap->sin_port = htons(port);
392 break;
393 case AF_INET6:
394 ap6->sin6_port = htons(port);
395 break;
396 }
397}
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 8b9affc8bab2..0adefc40cc89 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -209,6 +209,71 @@ out_mnt_err:
209 goto out; 209 goto out;
210} 210}
211 211
212/**
213 * nfs_umount - Notify a server that we have unmounted this export
214 * @info: pointer to umount request arguments
215 *
216 * MOUNTPROC_UMNT is advisory, so we set a short timeout, and always
217 * use UDP.
218 */
219void nfs_umount(const struct nfs_mount_request *info)
220{
221 static const struct rpc_timeout nfs_umnt_timeout = {
222 .to_initval = 1 * HZ,
223 .to_maxval = 3 * HZ,
224 .to_retries = 2,
225 };
226 struct rpc_create_args args = {
227 .protocol = IPPROTO_UDP,
228 .address = info->sap,
229 .addrsize = info->salen,
230 .timeout = &nfs_umnt_timeout,
231 .servername = info->hostname,
232 .program = &mnt_program,
233 .version = info->version,
234 .authflavor = RPC_AUTH_UNIX,
235 .flags = RPC_CLNT_CREATE_NOPING,
236 };
237 struct mountres result;
238 struct rpc_message msg = {
239 .rpc_argp = info->dirpath,
240 .rpc_resp = &result,
241 };
242 struct rpc_clnt *clnt;
243 int status;
244
245 if (info->noresvport)
246 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
247
248 clnt = rpc_create(&args);
249 if (unlikely(IS_ERR(clnt)))
250 goto out_clnt_err;
251
252 dprintk("NFS: sending UMNT request for %s:%s\n",
253 (info->hostname ? info->hostname : "server"), info->dirpath);
254
255 if (info->version == NFS_MNT3_VERSION)
256 msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC3_UMNT];
257 else
258 msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC_UMNT];
259
260 status = rpc_call_sync(clnt, &msg, 0);
261 rpc_shutdown_client(clnt);
262
263 if (unlikely(status < 0))
264 goto out_call_err;
265
266 return;
267
268out_clnt_err:
269 dprintk("NFS: failed to create UMNT RPC client, status=%ld\n",
270 PTR_ERR(clnt));
271 return;
272
273out_call_err:
274 dprintk("NFS: UMNT request failed, status=%d\n", status);
275}
276
212/* 277/*
213 * XDR encode/decode functions for MOUNT 278 * XDR encode/decode functions for MOUNT
214 */ 279 */
@@ -407,6 +472,13 @@ static struct rpc_procinfo mnt_procedures[] = {
407 .p_statidx = MOUNTPROC_MNT, 472 .p_statidx = MOUNTPROC_MNT,
408 .p_name = "MOUNT", 473 .p_name = "MOUNT",
409 }, 474 },
475 [MOUNTPROC_UMNT] = {
476 .p_proc = MOUNTPROC_UMNT,
477 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
478 .p_arglen = MNT_enc_dirpath_sz,
479 .p_statidx = MOUNTPROC_UMNT,
480 .p_name = "UMOUNT",
481 },
410}; 482};
411 483
412static struct rpc_procinfo mnt3_procedures[] = { 484static struct rpc_procinfo mnt3_procedures[] = {
@@ -419,6 +491,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
419 .p_statidx = MOUNTPROC3_MNT, 491 .p_statidx = MOUNTPROC3_MNT,
420 .p_name = "MOUNT", 492 .p_name = "MOUNT",
421 }, 493 },
494 [MOUNTPROC3_UMNT] = {
495 .p_proc = MOUNTPROC3_UMNT,
496 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
497 .p_arglen = MNT_enc_dirpath_sz,
498 .p_statidx = MOUNTPROC3_UMNT,
499 .p_name = "UMOUNT",
500 },
422}; 501};
423 502
424 503
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 2a2a0a7143ad..ef22ee89aa77 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -121,11 +121,11 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
121 121
122 if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) 122 if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
123 continue; 123 continue;
124 nfs_parse_ip_address(buf->data, buf->len, 124 mountdata->addrlen = rpc_pton(buf->data, buf->len,
125 mountdata->addr, &mountdata->addrlen); 125 mountdata->addr, mountdata->addrlen);
126 if (mountdata->addr->sa_family == AF_UNSPEC) 126 if (mountdata->addrlen == 0)
127 continue; 127 continue;
128 nfs_set_port(mountdata->addr, NFS_PORT); 128 rpc_set_port(mountdata->addr, NFS_PORT);
129 129
130 memcpy(page2, buf->data, buf->len); 130 memcpy(page2, buf->data, buf->len);
131 page2[buf->len] = '\0'; 131 page2[buf->len] = '\0';
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0b4cbdc60abd..9c85cdb353aa 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -158,7 +158,7 @@ static const match_table_t nfs_mount_option_tokens = {
158 { Opt_mountvers, "mountvers=%s" }, 158 { Opt_mountvers, "mountvers=%s" },
159 { Opt_nfsvers, "nfsvers=%s" }, 159 { Opt_nfsvers, "nfsvers=%s" },
160 { Opt_nfsvers, "vers=%s" }, 160 { Opt_nfsvers, "vers=%s" },
161 { Opt_minorversion, "minorversion=%u" }, 161 { Opt_minorversion, "minorversion=%s" },
162 162
163 { Opt_sec, "sec=%s" }, 163 { Opt_sec, "sec=%s" },
164 { Opt_proto, "proto=%s" }, 164 { Opt_proto, "proto=%s" },
@@ -742,129 +742,10 @@ static int nfs_verify_server_address(struct sockaddr *addr)
742 } 742 }
743 } 743 }
744 744
745 dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
745 return 0; 746 return 0;
746} 747}
747 748
748static void nfs_parse_ipv4_address(char *string, size_t str_len,
749 struct sockaddr *sap, size_t *addr_len)
750{
751 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
752 u8 *addr = (u8 *)&sin->sin_addr.s_addr;
753
754 if (str_len <= INET_ADDRSTRLEN) {
755 dfprintk(MOUNT, "NFS: parsing IPv4 address %*s\n",
756 (int)str_len, string);
757
758 sin->sin_family = AF_INET;
759 *addr_len = sizeof(*sin);
760 if (in4_pton(string, str_len, addr, '\0', NULL))
761 return;
762 }
763
764 sap->sa_family = AF_UNSPEC;
765 *addr_len = 0;
766}
767
768#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
769static int nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
770 const char *delim,
771 struct sockaddr_in6 *sin6)
772{
773 char *p;
774 size_t len;
775
776 if ((string + str_len) == delim)
777 return 1;
778
779 if (*delim != IPV6_SCOPE_DELIMITER)
780 return 0;
781
782 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
783 return 0;
784
785 len = (string + str_len) - delim - 1;
786 p = kstrndup(delim + 1, len, GFP_KERNEL);
787 if (p) {
788 unsigned long scope_id = 0;
789 struct net_device *dev;
790
791 dev = dev_get_by_name(&init_net, p);
792 if (dev != NULL) {
793 scope_id = dev->ifindex;
794 dev_put(dev);
795 } else {
796 if (strict_strtoul(p, 10, &scope_id) == 0) {
797 kfree(p);
798 return 0;
799 }
800 }
801
802 kfree(p);
803
804 sin6->sin6_scope_id = scope_id;
805 dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
806 return 1;
807 }
808
809 return 0;
810}
811
812static void nfs_parse_ipv6_address(char *string, size_t str_len,
813 struct sockaddr *sap, size_t *addr_len)
814{
815 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
816 u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
817 const char *delim;
818
819 if (str_len <= INET6_ADDRSTRLEN) {
820 dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n",
821 (int)str_len, string);
822
823 sin6->sin6_family = AF_INET6;
824 *addr_len = sizeof(*sin6);
825 if (in6_pton(string, str_len, addr,
826 IPV6_SCOPE_DELIMITER, &delim) != 0) {
827 if (nfs_parse_ipv6_scope_id(string, str_len,
828 delim, sin6) != 0)
829 return;
830 }
831 }
832
833 sap->sa_family = AF_UNSPEC;
834 *addr_len = 0;
835}
836#else
837static void nfs_parse_ipv6_address(char *string, size_t str_len,
838 struct sockaddr *sap, size_t *addr_len)
839{
840 sap->sa_family = AF_UNSPEC;
841 *addr_len = 0;
842}
843#endif
844
845/*
846 * Construct a sockaddr based on the contents of a string that contains
847 * an IP address in presentation format.
848 *
849 * If there is a problem constructing the new sockaddr, set the address
850 * family to AF_UNSPEC.
851 */
852void nfs_parse_ip_address(char *string, size_t str_len,
853 struct sockaddr *sap, size_t *addr_len)
854{
855 unsigned int i, colons;
856
857 colons = 0;
858 for (i = 0; i < str_len; i++)
859 if (string[i] == ':')
860 colons++;
861
862 if (colons >= 2)
863 nfs_parse_ipv6_address(string, str_len, sap, addr_len);
864 else
865 nfs_parse_ipv4_address(string, str_len, sap, addr_len);
866}
867
868/* 749/*
869 * Sanity check the NFS transport protocol. 750 * Sanity check the NFS transport protocol.
870 * 751 *
@@ -904,8 +785,6 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
904 785
905/* 786/*
906 * Parse the value of the 'sec=' option. 787 * Parse the value of the 'sec=' option.
907 *
908 * The flavor_len setting is for v4 mounts.
909 */ 788 */
910static int nfs_parse_security_flavors(char *value, 789static int nfs_parse_security_flavors(char *value,
911 struct nfs_parsed_mount_data *mnt) 790 struct nfs_parsed_mount_data *mnt)
@@ -916,53 +795,43 @@ static int nfs_parse_security_flavors(char *value,
916 795
917 switch (match_token(value, nfs_secflavor_tokens, args)) { 796 switch (match_token(value, nfs_secflavor_tokens, args)) {
918 case Opt_sec_none: 797 case Opt_sec_none:
919 mnt->auth_flavor_len = 0;
920 mnt->auth_flavors[0] = RPC_AUTH_NULL; 798 mnt->auth_flavors[0] = RPC_AUTH_NULL;
921 break; 799 break;
922 case Opt_sec_sys: 800 case Opt_sec_sys:
923 mnt->auth_flavor_len = 0;
924 mnt->auth_flavors[0] = RPC_AUTH_UNIX; 801 mnt->auth_flavors[0] = RPC_AUTH_UNIX;
925 break; 802 break;
926 case Opt_sec_krb5: 803 case Opt_sec_krb5:
927 mnt->auth_flavor_len = 1;
928 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; 804 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
929 break; 805 break;
930 case Opt_sec_krb5i: 806 case Opt_sec_krb5i:
931 mnt->auth_flavor_len = 1;
932 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; 807 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
933 break; 808 break;
934 case Opt_sec_krb5p: 809 case Opt_sec_krb5p:
935 mnt->auth_flavor_len = 1;
936 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; 810 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
937 break; 811 break;
938 case Opt_sec_lkey: 812 case Opt_sec_lkey:
939 mnt->auth_flavor_len = 1;
940 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; 813 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
941 break; 814 break;
942 case Opt_sec_lkeyi: 815 case Opt_sec_lkeyi:
943 mnt->auth_flavor_len = 1;
944 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; 816 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
945 break; 817 break;
946 case Opt_sec_lkeyp: 818 case Opt_sec_lkeyp:
947 mnt->auth_flavor_len = 1;
948 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; 819 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
949 break; 820 break;
950 case Opt_sec_spkm: 821 case Opt_sec_spkm:
951 mnt->auth_flavor_len = 1;
952 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; 822 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
953 break; 823 break;
954 case Opt_sec_spkmi: 824 case Opt_sec_spkmi:
955 mnt->auth_flavor_len = 1;
956 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; 825 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
957 break; 826 break;
958 case Opt_sec_spkmp: 827 case Opt_sec_spkmp:
959 mnt->auth_flavor_len = 1;
960 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; 828 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
961 break; 829 break;
962 default: 830 default:
963 return 0; 831 return 0;
964 } 832 }
965 833
834 mnt->auth_flavor_len = 1;
966 return 1; 835 return 1;
967} 836}
968 837
@@ -1001,7 +870,6 @@ static int nfs_parse_mount_options(char *raw,
1001 while ((p = strsep(&raw, ",")) != NULL) { 870 while ((p = strsep(&raw, ",")) != NULL) {
1002 substring_t args[MAX_OPT_ARGS]; 871 substring_t args[MAX_OPT_ARGS];
1003 unsigned long option; 872 unsigned long option;
1004 int int_option;
1005 int token; 873 int token;
1006 874
1007 if (!*p) 875 if (!*p)
@@ -1273,11 +1141,16 @@ static int nfs_parse_mount_options(char *raw,
1273 } 1141 }
1274 break; 1142 break;
1275 case Opt_minorversion: 1143 case Opt_minorversion:
1276 if (match_int(args, &int_option)) 1144 string = match_strdup(args);
1277 return 0; 1145 if (string == NULL)
1278 if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION) 1146 goto out_nomem;
1279 return 0; 1147 rc = strict_strtoul(string, 10, &option);
1280 mnt->minorversion = int_option; 1148 kfree(string);
1149 if (rc != 0)
1150 goto out_invalid_value;
1151 if (option > NFS4_MAX_MINOR_VERSION)
1152 goto out_invalid_value;
1153 mnt->minorversion = option;
1281 break; 1154 break;
1282 1155
1283 /* 1156 /*
@@ -1352,11 +1225,14 @@ static int nfs_parse_mount_options(char *raw,
1352 string = match_strdup(args); 1225 string = match_strdup(args);
1353 if (string == NULL) 1226 if (string == NULL)
1354 goto out_nomem; 1227 goto out_nomem;
1355 nfs_parse_ip_address(string, strlen(string), 1228 mnt->nfs_server.addrlen =
1356 (struct sockaddr *) 1229 rpc_pton(string, strlen(string),
1357 &mnt->nfs_server.address, 1230 (struct sockaddr *)
1358 &mnt->nfs_server.addrlen); 1231 &mnt->nfs_server.address,
1232 sizeof(mnt->nfs_server.address));
1359 kfree(string); 1233 kfree(string);
1234 if (mnt->nfs_server.addrlen == 0)
1235 goto out_invalid_address;
1360 break; 1236 break;
1361 case Opt_clientaddr: 1237 case Opt_clientaddr:
1362 string = match_strdup(args); 1238 string = match_strdup(args);
@@ -1376,11 +1252,14 @@ static int nfs_parse_mount_options(char *raw,
1376 string = match_strdup(args); 1252 string = match_strdup(args);
1377 if (string == NULL) 1253 if (string == NULL)
1378 goto out_nomem; 1254 goto out_nomem;
1379 nfs_parse_ip_address(string, strlen(string), 1255 mnt->mount_server.addrlen =
1380 (struct sockaddr *) 1256 rpc_pton(string, strlen(string),
1381 &mnt->mount_server.address, 1257 (struct sockaddr *)
1382 &mnt->mount_server.addrlen); 1258 &mnt->mount_server.address,
1259 sizeof(mnt->mount_server.address));
1383 kfree(string); 1260 kfree(string);
1261 if (mnt->mount_server.addrlen == 0)
1262 goto out_invalid_address;
1384 break; 1263 break;
1385 case Opt_lookupcache: 1264 case Opt_lookupcache:
1386 string = match_strdup(args); 1265 string = match_strdup(args);
@@ -1432,8 +1311,11 @@ static int nfs_parse_mount_options(char *raw,
1432 1311
1433 return 1; 1312 return 1;
1434 1313
1314out_invalid_address:
1315 printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
1316 return 0;
1435out_invalid_value: 1317out_invalid_value:
1436 printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p); 1318 printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
1437 return 0; 1319 return 0;
1438out_nomem: 1320out_nomem:
1439 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1321 printk(KERN_INFO "NFS: not enough memory to parse option\n");
@@ -1445,13 +1327,50 @@ out_security_failure:
1445} 1327}
1446 1328
1447/* 1329/*
1330 * Match the requested auth flavors with the list returned by
1331 * the server. Returns zero and sets the mount's authentication
1332 * flavor on success; returns -EACCES if server does not support
1333 * the requested flavor.
1334 */
1335static int nfs_walk_authlist(struct nfs_parsed_mount_data *args,
1336 struct nfs_mount_request *request)
1337{
1338 unsigned int i, j, server_authlist_len = *(request->auth_flav_len);
1339
1340 /*
1341 * We avoid sophisticated negotiating here, as there are
1342 * plenty of cases where we can get it wrong, providing
1343 * either too little or too much security.
1344 *
1345 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1346 * flavor listed first. However, some servers list
1347 * AUTH_NULL first. Our caller plants AUTH_SYS, the
1348 * preferred default, in args->auth_flavors[0] if user
1349 * didn't specify sec= mount option.
1350 */
1351 for (i = 0; i < args->auth_flavor_len; i++)
1352 for (j = 0; j < server_authlist_len; j++)
1353 if (args->auth_flavors[i] == request->auth_flavs[j]) {
1354 dfprintk(MOUNT, "NFS: using auth flavor %d\n",
1355 request->auth_flavs[j]);
1356 args->auth_flavors[0] = request->auth_flavs[j];
1357 return 0;
1358 }
1359
1360 dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n");
1361 nfs_umount(request);
1362 return -EACCES;
1363}
1364
1365/*
1448 * Use the remote server's MOUNT service to request the NFS file handle 1366 * Use the remote server's MOUNT service to request the NFS file handle
1449 * corresponding to the provided path. 1367 * corresponding to the provided path.
1450 */ 1368 */
1451static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1369static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1452 struct nfs_fh *root_fh) 1370 struct nfs_fh *root_fh)
1453{ 1371{
1454 unsigned int auth_flavor_len = 0; 1372 rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
1373 unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
1455 struct nfs_mount_request request = { 1374 struct nfs_mount_request request = {
1456 .sap = (struct sockaddr *) 1375 .sap = (struct sockaddr *)
1457 &args->mount_server.address, 1376 &args->mount_server.address,
@@ -1459,7 +1378,8 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1459 .protocol = args->mount_server.protocol, 1378 .protocol = args->mount_server.protocol,
1460 .fh = root_fh, 1379 .fh = root_fh,
1461 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1380 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1462 .auth_flav_len = &auth_flavor_len, 1381 .auth_flav_len = &server_authlist_len,
1382 .auth_flavs = server_authlist,
1463 }; 1383 };
1464 int status; 1384 int status;
1465 1385
@@ -1489,19 +1409,25 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1489 /* 1409 /*
1490 * autobind will be used if mount_server.port == 0 1410 * autobind will be used if mount_server.port == 0
1491 */ 1411 */
1492 nfs_set_port(request.sap, args->mount_server.port); 1412 rpc_set_port(request.sap, args->mount_server.port);
1493 1413
1494 /* 1414 /*
1495 * Now ask the mount server to map our export path 1415 * Now ask the mount server to map our export path
1496 * to a file handle. 1416 * to a file handle.
1497 */ 1417 */
1498 status = nfs_mount(&request); 1418 status = nfs_mount(&request);
1499 if (status == 0) 1419 if (status != 0) {
1500 return 0; 1420 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
1421 request.hostname, status);
1422 return status;
1423 }
1501 1424
1502 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", 1425 /*
1503 request.hostname, status); 1426 * MNTv1 (NFSv2) does not support auth flavor negotiation.
1504 return status; 1427 */
1428 if (args->mount_server.version != NFS_MNT3_VERSION)
1429 return 0;
1430 return nfs_walk_authlist(args, &request);
1505} 1431}
1506 1432
1507static int nfs_parse_simple_hostname(const char *dev_name, 1433static int nfs_parse_simple_hostname(const char *dev_name,
@@ -1676,6 +1602,7 @@ static int nfs_validate_mount_data(void *options,
1676 args->nfs_server.port = 0; /* autobind unless user sets port */ 1602 args->nfs_server.port = 0; /* autobind unless user sets port */
1677 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1603 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1678 args->auth_flavors[0] = RPC_AUTH_UNIX; 1604 args->auth_flavors[0] = RPC_AUTH_UNIX;
1605 args->auth_flavor_len = 1;
1679 1606
1680 switch (data->version) { 1607 switch (data->version) {
1681 case 1: 1608 case 1:
@@ -1776,7 +1703,7 @@ static int nfs_validate_mount_data(void *options,
1776 &args->nfs_server.address)) 1703 &args->nfs_server.address))
1777 goto out_no_address; 1704 goto out_no_address;
1778 1705
1779 nfs_set_port((struct sockaddr *)&args->nfs_server.address, 1706 rpc_set_port((struct sockaddr *)&args->nfs_server.address,
1780 args->nfs_server.port); 1707 args->nfs_server.port);
1781 1708
1782 nfs_set_mount_transport_protocol(args); 1709 nfs_set_mount_transport_protocol(args);
@@ -2339,7 +2266,7 @@ static int nfs4_validate_mount_data(void *options,
2339 args->acdirmax = NFS_DEF_ACDIRMAX; 2266 args->acdirmax = NFS_DEF_ACDIRMAX;
2340 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ 2267 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
2341 args->auth_flavors[0] = RPC_AUTH_UNIX; 2268 args->auth_flavors[0] = RPC_AUTH_UNIX;
2342 args->auth_flavor_len = 0; 2269 args->auth_flavor_len = 1;
2343 args->minorversion = 0; 2270 args->minorversion = 0;
2344 2271
2345 switch (data->version) { 2272 switch (data->version) {
@@ -2409,7 +2336,7 @@ static int nfs4_validate_mount_data(void *options,
2409 &args->nfs_server.address)) 2336 &args->nfs_server.address))
2410 return -EINVAL; 2337 return -EINVAL;
2411 2338
2412 nfs_set_port((struct sockaddr *)&args->nfs_server.address, 2339 rpc_set_port((struct sockaddr *)&args->nfs_server.address,
2413 args->nfs_server.port); 2340 args->nfs_server.port);
2414 2341
2415 nfs_validate_transport_protocol(args); 2342 nfs_validate_transport_protocol(args);
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 6d0847562d87..7e906c5b7671 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -37,6 +37,7 @@
37#include <linux/nfsd/xdr.h> 37#include <linux/nfsd/xdr.h>
38#include <linux/nfsd/syscall.h> 38#include <linux/nfsd/syscall.h>
39#include <linux/lockd/lockd.h> 39#include <linux/lockd/lockd.h>
40#include <linux/sunrpc/clnt.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <net/ipv6.h> 43#include <net/ipv6.h>
@@ -490,22 +491,18 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size)
490 * 491 *
491 * Input: 492 * Input:
492 * buf: '\n'-terminated C string containing a 493 * buf: '\n'-terminated C string containing a
493 * presentation format IPv4 address 494 * presentation format IP address
494 * size: length of C string in @buf 495 * size: length of C string in @buf
495 * Output: 496 * Output:
496 * On success: returns zero if all specified locks were released; 497 * On success: returns zero if all specified locks were released;
497 * returns one if one or more locks were not released 498 * returns one if one or more locks were not released
498 * On error: return code is negative errno value 499 * On error: return code is negative errno value
499 *
500 * Note: Only AF_INET client addresses are passed in
501 */ 500 */
502static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size) 501static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
503{ 502{
504 struct sockaddr_in sin = { 503 struct sockaddr_storage address;
505 .sin_family = AF_INET, 504 struct sockaddr *sap = (struct sockaddr *)&address;
506 }; 505 size_t salen = sizeof(address);
507 int b1, b2, b3, b4;
508 char c;
509 char *fo_path; 506 char *fo_path;
510 507
511 /* sanity check */ 508 /* sanity check */
@@ -519,14 +516,10 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
519 if (qword_get(&buf, fo_path, size) < 0) 516 if (qword_get(&buf, fo_path, size) < 0)
520 return -EINVAL; 517 return -EINVAL;
521 518
522 /* get ipv4 address */ 519 if (rpc_pton(fo_path, size, sap, salen) == 0)
523 if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
524 return -EINVAL;
525 if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255)
526 return -EINVAL; 520 return -EINVAL;
527 sin.sin_addr.s_addr = htonl((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
528 521
529 return nlmsvc_unlock_all_by_ip((struct sockaddr *)&sin); 522 return nlmsvc_unlock_all_by_ip(sap);
530} 523}
531 524
532/** 525/**
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 37881f1a0bd7..2636e8ad551c 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -9,6 +9,10 @@
9#ifndef _LINUX_SUNRPC_CLNT_H 9#ifndef _LINUX_SUNRPC_CLNT_H
10#define _LINUX_SUNRPC_CLNT_H 10#define _LINUX_SUNRPC_CLNT_H
11 11
12#include <linux/socket.h>
13#include <linux/in.h>
14#include <linux/in6.h>
15
12#include <linux/sunrpc/msg_prot.h> 16#include <linux/sunrpc/msg_prot.h>
13#include <linux/sunrpc/sched.h> 17#include <linux/sunrpc/sched.h>
14#include <linux/sunrpc/xprt.h> 18#include <linux/sunrpc/xprt.h>
@@ -151,5 +155,39 @@ void rpc_force_rebind(struct rpc_clnt *);
151size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); 155size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
152const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); 156const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
153 157
158size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
159size_t rpc_pton(const char *, const size_t,
160 struct sockaddr *, const size_t);
161char * rpc_sockaddr2uaddr(const struct sockaddr *);
162size_t rpc_uaddr2sockaddr(const char *, const size_t,
163 struct sockaddr *, const size_t);
164
165static inline unsigned short rpc_get_port(const struct sockaddr *sap)
166{
167 switch (sap->sa_family) {
168 case AF_INET:
169 return ntohs(((struct sockaddr_in *)sap)->sin_port);
170 case AF_INET6:
171 return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
172 }
173 return 0;
174}
175
176static inline void rpc_set_port(struct sockaddr *sap,
177 const unsigned short port)
178{
179 switch (sap->sa_family) {
180 case AF_INET:
181 ((struct sockaddr_in *)sap)->sin_port = htons(port);
182 break;
183 case AF_INET6:
184 ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
185 break;
186 }
187}
188
189#define IPV6_SCOPE_DELIMITER '%'
190#define IPV6_SCOPE_ID_LEN sizeof("%nnnnnnnnnn")
191
154#endif /* __KERNEL__ */ 192#endif /* __KERNEL__ */
155#endif /* _LINUX_SUNRPC_CLNT_H */ 193#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 70df4f1d8847..77e624883393 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -189,7 +189,22 @@ typedef __be32 rpc_fraghdr;
189 * Additionally, the two alternative forms specified in Section 2.2 of 189 * Additionally, the two alternative forms specified in Section 2.2 of
190 * [RFC2373] are also acceptable. 190 * [RFC2373] are also acceptable.
191 */ 191 */
192#define RPCBIND_MAXUADDRLEN (56u) 192
193#include <linux/inet.h>
194
195/* Maximum size of the port number part of a universal address */
196#define RPCBIND_MAXUADDRPLEN sizeof(".255.255")
197
198/* Maximum size of an IPv4 universal address */
199#define RPCBIND_MAXUADDR4LEN \
200 (INET_ADDRSTRLEN + RPCBIND_MAXUADDRPLEN)
201
202/* Maximum size of an IPv6 universal address */
203#define RPCBIND_MAXUADDR6LEN \
204 (INET6_ADDRSTRLEN + RPCBIND_MAXUADDRPLEN)
205
206/* Assume INET6_ADDRSTRLEN will always be larger than INET_ADDRSTRLEN... */
207#define RPCBIND_MAXUADDRLEN RPCBIND_MAXUADDR6LEN
193 208
194#endif /* __KERNEL__ */ 209#endif /* __KERNEL__ */
195#endif /* _LINUX_SUNRPC_MSGPROT_H_ */ 210#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 1175d58efc2e..c090df442572 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -38,10 +38,8 @@ enum rpc_display_format_t {
38 RPC_DISPLAY_ADDR = 0, 38 RPC_DISPLAY_ADDR = 0,
39 RPC_DISPLAY_PORT, 39 RPC_DISPLAY_PORT,
40 RPC_DISPLAY_PROTO, 40 RPC_DISPLAY_PROTO,
41 RPC_DISPLAY_ALL,
42 RPC_DISPLAY_HEX_ADDR, 41 RPC_DISPLAY_HEX_ADDR,
43 RPC_DISPLAY_HEX_PORT, 42 RPC_DISPLAY_HEX_PORT,
44 RPC_DISPLAY_UNIVERSAL_ADDR,
45 RPC_DISPLAY_NETID, 43 RPC_DISPLAY_NETID,
46 RPC_DISPLAY_MAX, 44 RPC_DISPLAY_MAX,
47}; 45};
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index db73fd2a3f0e..9d2fca5ad14a 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/
10sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ 10sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
11 auth.o auth_null.o auth_unix.o auth_generic.o \ 11 auth.o auth_null.o auth_unix.o auth_generic.o \
12 svc.o svcsock.o svcauth.o svcauth_unix.o \ 12 svc.o svcsock.o svcauth.o svcauth_unix.o \
13 rpcb_clnt.o timer.o xdr.o \ 13 addr.o rpcb_clnt.o timer.o xdr.o \
14 sunrpc_syms.o cache.o rpc_pipe.o \ 14 sunrpc_syms.o cache.o rpc_pipe.o \
15 svc_xprt.o 15 svc_xprt.o
16sunrpc-$(CONFIG_NFS_V4_1) += backchannel_rqst.o bc_svc.o 16sunrpc-$(CONFIG_NFS_V4_1) += backchannel_rqst.o bc_svc.o
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
new file mode 100644
index 000000000000..22e8fd89477f
--- /dev/null
+++ b/net/sunrpc/addr.c
@@ -0,0 +1,364 @@
1/*
2 * Copyright 2009, Oracle. All rights reserved.
3 *
4 * Convert socket addresses to presentation addresses and universal
5 * addresses, and vice versa.
6 *
7 * Universal addresses are introduced by RFC 1833 and further refined by
8 * recent RFCs describing NFSv4. The universal address format is part
9 * of the external (network) interface provided by rpcbind version 3
10 * and 4, and by NFSv4. Such an address is a string containing a
11 * presentation format IP address followed by a port number in
12 * "hibyte.lobyte" format.
13 *
14 * IPv6 addresses can also include a scope ID, typically denoted by
15 * a '%' followed by a device name or a non-negative integer. Refer to
16 * RFC 4291, Section 2.2 for details on IPv6 presentation formats.
17 */
18
19#include <net/ipv6.h>
20#include <linux/sunrpc/clnt.h>
21
22#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
23
24static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
25 char *buf, const int buflen)
26{
27 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
28 const struct in6_addr *addr = &sin6->sin6_addr;
29
30 /*
31 * RFC 4291, Section 2.2.2
32 *
33 * Shorthanded ANY address
34 */
35 if (ipv6_addr_any(addr))
36 return snprintf(buf, buflen, "::");
37
38 /*
39 * RFC 4291, Section 2.2.2
40 *
41 * Shorthanded loopback address
42 */
43 if (ipv6_addr_loopback(addr))
44 return snprintf(buf, buflen, "::1");
45
46 /*
47 * RFC 4291, Section 2.2.3
48 *
49 * Special presentation address format for mapped v4
50 * addresses.
51 */
52 if (ipv6_addr_v4mapped(addr))
53 return snprintf(buf, buflen, "::ffff:%pI4",
54 &addr->s6_addr32[3]);
55
56 /*
57 * RFC 4291, Section 2.2.1
58 *
59 * To keep the result as short as possible, especially
60 * since we don't shorthand, we don't want leading zeros
61 * in each halfword, so avoid %pI6.
62 */
63 return snprintf(buf, buflen, "%x:%x:%x:%x:%x:%x:%x:%x",
64 ntohs(addr->s6_addr16[0]), ntohs(addr->s6_addr16[1]),
65 ntohs(addr->s6_addr16[2]), ntohs(addr->s6_addr16[3]),
66 ntohs(addr->s6_addr16[4]), ntohs(addr->s6_addr16[5]),
67 ntohs(addr->s6_addr16[6]), ntohs(addr->s6_addr16[7]));
68}
69
70static size_t rpc_ntop6(const struct sockaddr *sap,
71 char *buf, const size_t buflen)
72{
73 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
74 char scopebuf[IPV6_SCOPE_ID_LEN];
75 size_t len;
76 int rc;
77
78 len = rpc_ntop6_noscopeid(sap, buf, buflen);
79 if (unlikely(len == 0))
80 return len;
81
82 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
83 !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
84 return len;
85
86 rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u",
87 IPV6_SCOPE_DELIMITER, sin6->sin6_scope_id);
88 if (unlikely((size_t)rc > sizeof(scopebuf)))
89 return 0;
90
91 len += rc;
92 if (unlikely(len > buflen))
93 return 0;
94
95 strcat(buf, scopebuf);
96 return len;
97}
98
99#else /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
100
101static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
102 char *buf, const int buflen)
103{
104 return 0;
105}
106
107static size_t rpc_ntop6(const struct sockaddr *sap,
108 char *buf, const size_t buflen)
109{
110 return 0;
111}
112
113#endif /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
114
115static int rpc_ntop4(const struct sockaddr *sap,
116 char *buf, const size_t buflen)
117{
118 const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
119
120 return snprintf(buf, buflen, "%pI4", &sin->sin_addr);
121}
122
123/**
124 * rpc_ntop - construct a presentation address in @buf
125 * @sap: socket address
126 * @buf: construction area
127 * @buflen: size of @buf, in bytes
128 *
129 * Plants a %NUL-terminated string in @buf and returns the length
130 * of the string, excluding the %NUL. Otherwise zero is returned.
131 */
132size_t rpc_ntop(const struct sockaddr *sap, char *buf, const size_t buflen)
133{
134 switch (sap->sa_family) {
135 case AF_INET:
136 return rpc_ntop4(sap, buf, buflen);
137 case AF_INET6:
138 return rpc_ntop6(sap, buf, buflen);
139 }
140
141 return 0;
142}
143EXPORT_SYMBOL_GPL(rpc_ntop);
144
145static size_t rpc_pton4(const char *buf, const size_t buflen,
146 struct sockaddr *sap, const size_t salen)
147{
148 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
149 u8 *addr = (u8 *)&sin->sin_addr.s_addr;
150
151 if (buflen > INET_ADDRSTRLEN || salen < sizeof(struct sockaddr_in))
152 return 0;
153
154 memset(sap, 0, sizeof(struct sockaddr_in));
155
156 if (in4_pton(buf, buflen, addr, '\0', NULL) == 0)
157 return 0;
158
159 sin->sin_family = AF_INET;
160 return sizeof(struct sockaddr_in);;
161}
162
163#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
164static int rpc_parse_scope_id(const char *buf, const size_t buflen,
165 const char *delim, struct sockaddr_in6 *sin6)
166{
167 char *p;
168 size_t len;
169
170 if ((buf + buflen) == delim)
171 return 1;
172
173 if (*delim != IPV6_SCOPE_DELIMITER)
174 return 0;
175
176 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
177 !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
178 return 0;
179
180 len = (buf + buflen) - delim - 1;
181 p = kstrndup(delim + 1, len, GFP_KERNEL);
182 if (p) {
183 unsigned long scope_id = 0;
184 struct net_device *dev;
185
186 dev = dev_get_by_name(&init_net, p);
187 if (dev != NULL) {
188 scope_id = dev->ifindex;
189 dev_put(dev);
190 } else {
191 if (strict_strtoul(p, 10, &scope_id) == 0) {
192 kfree(p);
193 return 0;
194 }
195 }
196
197 kfree(p);
198
199 sin6->sin6_scope_id = scope_id;
200 return 1;
201 }
202
203 return 0;
204}
205
206static size_t rpc_pton6(const char *buf, const size_t buflen,
207 struct sockaddr *sap, const size_t salen)
208{
209 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
210 u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
211 const char *delim;
212
213 if (buflen > (INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN) ||
214 salen < sizeof(struct sockaddr_in6))
215 return 0;
216
217 memset(sap, 0, sizeof(struct sockaddr_in6));
218
219 if (in6_pton(buf, buflen, addr, IPV6_SCOPE_DELIMITER, &delim) == 0)
220 return 0;
221
222 if (!rpc_parse_scope_id(buf, buflen, delim, sin6))
223 return 0;
224
225 sin6->sin6_family = AF_INET6;
226 return sizeof(struct sockaddr_in6);
227}
228#else
229static size_t rpc_pton6(const char *buf, const size_t buflen,
230 struct sockaddr *sap, const size_t salen)
231{
232 return 0;
233}
234#endif
235
236/**
237 * rpc_pton - Construct a sockaddr in @sap
238 * @buf: C string containing presentation format IP address
239 * @buflen: length of presentation address in bytes
240 * @sap: buffer into which to plant socket address
241 * @salen: size of buffer in bytes
242 *
243 * Returns the size of the socket address if successful; otherwise
244 * zero is returned.
245 *
246 * Plants a socket address in @sap and returns the size of the
247 * socket address, if successful. Returns zero if an error
248 * occurred.
249 */
250size_t rpc_pton(const char *buf, const size_t buflen,
251 struct sockaddr *sap, const size_t salen)
252{
253 unsigned int i;
254
255 for (i = 0; i < buflen; i++)
256 if (buf[i] == ':')
257 return rpc_pton6(buf, buflen, sap, salen);
258 return rpc_pton4(buf, buflen, sap, salen);
259}
260EXPORT_SYMBOL_GPL(rpc_pton);
261
262/**
263 * rpc_sockaddr2uaddr - Construct a universal address string from @sap.
264 * @sap: socket address
265 *
266 * Returns a %NUL-terminated string in dynamically allocated memory;
267 * otherwise NULL is returned if an error occurred. Caller must
268 * free the returned string.
269 */
270char *rpc_sockaddr2uaddr(const struct sockaddr *sap)
271{
272 char portbuf[RPCBIND_MAXUADDRPLEN];
273 char addrbuf[RPCBIND_MAXUADDRLEN];
274 unsigned short port;
275
276 switch (sap->sa_family) {
277 case AF_INET:
278 if (rpc_ntop4(sap, addrbuf, sizeof(addrbuf)) == 0)
279 return NULL;
280 port = ntohs(((struct sockaddr_in *)sap)->sin_port);
281 break;
282 case AF_INET6:
283 if (rpc_ntop6_noscopeid(sap, addrbuf, sizeof(addrbuf)) == 0)
284 return NULL;
285 port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
286 break;
287 default:
288 return NULL;
289 }
290
291 if (snprintf(portbuf, sizeof(portbuf),
292 ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf))
293 return NULL;
294
295 if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
296 return NULL;
297
298 return kstrdup(addrbuf, GFP_KERNEL);
299}
300EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
301
302/**
303 * rpc_uaddr2sockaddr - convert a universal address to a socket address.
304 * @uaddr: C string containing universal address to convert
305 * @uaddr_len: length of universal address string
306 * @sap: buffer into which to plant socket address
307 * @salen: size of buffer
308 *
309 * Returns the size of the socket address if successful; otherwise
310 * zero is returned.
311 */
312size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
313 struct sockaddr *sap, const size_t salen)
314{
315 char *c, buf[RPCBIND_MAXUADDRLEN];
316 unsigned long portlo, porthi;
317 unsigned short port;
318
319 if (uaddr_len > sizeof(buf))
320 return 0;
321
322 memcpy(buf, uaddr, uaddr_len);
323
324 buf[uaddr_len] = '\n';
325 buf[uaddr_len + 1] = '\0';
326
327 c = strrchr(buf, '.');
328 if (unlikely(c == NULL))
329 return 0;
330 if (unlikely(strict_strtoul(c + 1, 10, &portlo) != 0))
331 return 0;
332 if (unlikely(portlo > 255))
333 return 0;
334
335 c[0] = '\n';
336 c[1] = '\0';
337
338 c = strrchr(buf, '.');
339 if (unlikely(c == NULL))
340 return 0;
341 if (unlikely(strict_strtoul(c + 1, 10, &porthi) != 0))
342 return 0;
343 if (unlikely(porthi > 255))
344 return 0;
345
346 port = (unsigned short)((porthi << 8) | portlo);
347
348 c[0] = '\0';
349
350 if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
351 return 0;
352
353 switch (sap->sa_family) {
354 case AF_INET:
355 ((struct sockaddr_in *)sap)->sin_port = htons(port);
356 return sizeof(struct sockaddr_in);
357 case AF_INET6:
358 ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
359 return sizeof(struct sockaddr_in6);
360 }
361
362 return 0;
363}
364EXPORT_SYMBOL_GPL(rpc_uaddr2sockaddr);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index beee6da33035..830faf4d9997 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -75,6 +75,37 @@ enum {
75#define RPCB_OWNER_STRING "0" 75#define RPCB_OWNER_STRING "0"
76#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING) 76#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
77 77
78/*
79 * XDR data type sizes
80 */
81#define RPCB_program_sz (1)
82#define RPCB_version_sz (1)
83#define RPCB_protocol_sz (1)
84#define RPCB_port_sz (1)
85#define RPCB_boolean_sz (1)
86
87#define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
88#define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
89#define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
90
91/*
92 * XDR argument and result sizes
93 */
94#define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
95 RPCB_protocol_sz + RPCB_port_sz)
96#define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
97 RPCB_netid_sz + RPCB_addr_sz + \
98 RPCB_ownerstring_sz)
99
100#define RPCB_getportres_sz RPCB_port_sz
101#define RPCB_setres_sz RPCB_boolean_sz
102
103/*
104 * Note that RFC 1833 does not put any size restrictions on the
105 * address string returned by the remote rpcbind database.
106 */
107#define RPCB_getaddrres_sz RPCB_addr_sz
108
78static void rpcb_getport_done(struct rpc_task *, void *); 109static void rpcb_getport_done(struct rpc_task *, void *);
79static void rpcb_map_release(void *data); 110static void rpcb_map_release(void *data);
80static struct rpc_program rpcb_program; 111static struct rpc_program rpcb_program;
@@ -122,6 +153,7 @@ static void rpcb_map_release(void *data)
122 153
123 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status); 154 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
124 xprt_put(map->r_xprt); 155 xprt_put(map->r_xprt);
156 kfree(map->r_addr);
125 kfree(map); 157 kfree(map);
126} 158}
127 159
@@ -268,12 +300,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
268 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; 300 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
269 struct rpcbind_args *map = msg->rpc_argp; 301 struct rpcbind_args *map = msg->rpc_argp;
270 unsigned short port = ntohs(sin->sin_port); 302 unsigned short port = ntohs(sin->sin_port);
271 char buf[32]; 303 int result;
272 304
273 /* Construct AF_INET universal address */ 305 map->r_addr = rpc_sockaddr2uaddr(sap);
274 snprintf(buf, sizeof(buf), "%pI4.%u.%u",
275 &sin->sin_addr.s_addr, port >> 8, port & 0xff);
276 map->r_addr = buf;
277 306
278 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " 307 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
279 "local rpcbind\n", (port ? "" : "un"), 308 "local rpcbind\n", (port ? "" : "un"),
@@ -284,7 +313,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
284 if (port) 313 if (port)
285 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 314 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
286 315
287 return rpcb_register_call(RPCBVERS_4, msg); 316 result = rpcb_register_call(RPCBVERS_4, msg);
317 kfree(map->r_addr);
318 return result;
288} 319}
289 320
290/* 321/*
@@ -296,16 +327,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
296 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap; 327 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
297 struct rpcbind_args *map = msg->rpc_argp; 328 struct rpcbind_args *map = msg->rpc_argp;
298 unsigned short port = ntohs(sin6->sin6_port); 329 unsigned short port = ntohs(sin6->sin6_port);
299 char buf[64]; 330 int result;
300 331
301 /* Construct AF_INET6 universal address */ 332 map->r_addr = rpc_sockaddr2uaddr(sap);
302 if (ipv6_addr_any(&sin6->sin6_addr))
303 snprintf(buf, sizeof(buf), "::.%u.%u",
304 port >> 8, port & 0xff);
305 else
306 snprintf(buf, sizeof(buf), "%pI6.%u.%u",
307 &sin6->sin6_addr, port >> 8, port & 0xff);
308 map->r_addr = buf;
309 333
310 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " 334 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
311 "local rpcbind\n", (port ? "" : "un"), 335 "local rpcbind\n", (port ? "" : "un"),
@@ -316,7 +340,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
316 if (port) 340 if (port)
317 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 341 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
318 342
319 return rpcb_register_call(RPCBVERS_4, msg); 343 result = rpcb_register_call(RPCBVERS_4, msg);
344 kfree(map->r_addr);
345 return result;
320} 346}
321 347
322static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) 348static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
@@ -428,7 +454,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
428 struct rpc_message msg = { 454 struct rpc_message msg = {
429 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], 455 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
430 .rpc_argp = &map, 456 .rpc_argp = &map,
431 .rpc_resp = &map.r_port, 457 .rpc_resp = &map,
432 }; 458 };
433 struct rpc_clnt *rpcb_clnt; 459 struct rpc_clnt *rpcb_clnt;
434 int status; 460 int status;
@@ -458,7 +484,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
458 struct rpc_message msg = { 484 struct rpc_message msg = {
459 .rpc_proc = proc, 485 .rpc_proc = proc,
460 .rpc_argp = map, 486 .rpc_argp = map,
461 .rpc_resp = &map->r_port, 487 .rpc_resp = map,
462 }; 488 };
463 struct rpc_task_setup task_setup_data = { 489 struct rpc_task_setup task_setup_data = {
464 .rpc_client = rpcb_clnt, 490 .rpc_client = rpcb_clnt,
@@ -539,6 +565,7 @@ void rpcb_getport_async(struct rpc_task *task)
539 goto bailout_nofree; 565 goto bailout_nofree;
540 } 566 }
541 567
568 /* Parent transport's destination address */
542 salen = rpc_peeraddr(clnt, sap, sizeof(addr)); 569 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
543 570
544 /* Don't ever use rpcbind v2 for AF_INET6 requests */ 571 /* Don't ever use rpcbind v2 for AF_INET6 requests */
@@ -589,11 +616,22 @@ void rpcb_getport_async(struct rpc_task *task)
589 map->r_prot = xprt->prot; 616 map->r_prot = xprt->prot;
590 map->r_port = 0; 617 map->r_port = 0;
591 map->r_xprt = xprt_get(xprt); 618 map->r_xprt = xprt_get(xprt);
592 map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
593 map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
594 map->r_owner = "";
595 map->r_status = -EIO; 619 map->r_status = -EIO;
596 620
621 switch (bind_version) {
622 case RPCBVERS_4:
623 case RPCBVERS_3:
624 map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
625 map->r_addr = rpc_sockaddr2uaddr(sap);
626 map->r_owner = "";
627 break;
628 case RPCBVERS_2:
629 map->r_addr = NULL;
630 break;
631 default:
632 BUG();
633 }
634
597 child = rpcb_call_async(rpcb_clnt, map, proc); 635 child = rpcb_call_async(rpcb_clnt, map, proc);
598 rpc_release_client(rpcb_clnt); 636 rpc_release_client(rpcb_clnt);
599 if (IS_ERR(child)) { 637 if (IS_ERR(child)) {
@@ -656,176 +694,278 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
656 * XDR functions for rpcbind 694 * XDR functions for rpcbind
657 */ 695 */
658 696
659static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, 697static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p,
660 struct rpcbind_args *rpcb) 698 const struct rpcbind_args *rpcb)
661{ 699{
662 dprintk("RPC: encoding rpcb request (%u, %u, %d, %u)\n", 700 struct rpc_task *task = req->rq_task;
701 struct xdr_stream xdr;
702
703 dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
704 task->tk_pid, task->tk_msg.rpc_proc->p_name,
663 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); 705 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
706
707 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
708
709 p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz);
710 if (unlikely(p == NULL))
711 return -EIO;
712
664 *p++ = htonl(rpcb->r_prog); 713 *p++ = htonl(rpcb->r_prog);
665 *p++ = htonl(rpcb->r_vers); 714 *p++ = htonl(rpcb->r_vers);
666 *p++ = htonl(rpcb->r_prot); 715 *p++ = htonl(rpcb->r_prot);
667 *p++ = htonl(rpcb->r_port); 716 *p = htonl(rpcb->r_port);
668 717
669 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
670 return 0; 718 return 0;
671} 719}
672 720
673static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p, 721static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p,
674 unsigned short *portp) 722 struct rpcbind_args *rpcb)
675{ 723{
676 *portp = (unsigned short) ntohl(*p++); 724 struct rpc_task *task = req->rq_task;
677 dprintk("RPC: rpcb getport result: %u\n", 725 struct xdr_stream xdr;
678 *portp); 726 unsigned long port;
727
728 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
729
730 rpcb->r_port = 0;
731
732 p = xdr_inline_decode(&xdr, sizeof(__be32));
733 if (unlikely(p == NULL))
734 return -EIO;
735
736 port = ntohl(*p);
737 dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid,
738 task->tk_msg.rpc_proc->p_name, port);
739 if (unlikely(port > USHORT_MAX))
740 return -EIO;
741
742 rpcb->r_port = port;
679 return 0; 743 return 0;
680} 744}
681 745
682static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p, 746static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p,
683 unsigned int *boolp) 747 unsigned int *boolp)
684{ 748{
685 *boolp = (unsigned int) ntohl(*p++); 749 struct rpc_task *task = req->rq_task;
686 dprintk("RPC: rpcb set/unset call %s\n", 750 struct xdr_stream xdr;
751
752 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
753
754 p = xdr_inline_decode(&xdr, sizeof(__be32));
755 if (unlikely(p == NULL))
756 return -EIO;
757
758 *boolp = 0;
759 if (*p)
760 *boolp = 1;
761
762 dprintk("RPC: %5u RPCB_%s call %s\n",
763 task->tk_pid, task->tk_msg.rpc_proc->p_name,
687 (*boolp ? "succeeded" : "failed")); 764 (*boolp ? "succeeded" : "failed"));
688 return 0; 765 return 0;
689} 766}
690 767
691static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p, 768static int encode_rpcb_string(struct xdr_stream *xdr, const char *string,
692 struct rpcbind_args *rpcb) 769 const u32 maxstrlen)
693{ 770{
694 dprintk("RPC: encoding rpcb request (%u, %u, %s)\n", 771 u32 len;
695 rpcb->r_prog, rpcb->r_vers, rpcb->r_addr); 772 __be32 *p;
696 *p++ = htonl(rpcb->r_prog);
697 *p++ = htonl(rpcb->r_vers);
698 773
699 p = xdr_encode_string(p, rpcb->r_netid); 774 if (unlikely(string == NULL))
700 p = xdr_encode_string(p, rpcb->r_addr); 775 return -EIO;
701 p = xdr_encode_string(p, rpcb->r_owner); 776 len = strlen(string);
777 if (unlikely(len > maxstrlen))
778 return -EIO;
702 779
703 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); 780 p = xdr_reserve_space(xdr, sizeof(__be32) + len);
781 if (unlikely(p == NULL))
782 return -EIO;
783 xdr_encode_opaque(p, string, len);
704 784
705 return 0; 785 return 0;
706} 786}
707 787
708static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p, 788static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p,
709 unsigned short *portp) 789 const struct rpcbind_args *rpcb)
710{ 790{
711 char *addr; 791 struct rpc_task *task = req->rq_task;
712 u32 addr_len; 792 struct xdr_stream xdr;
713 int c, i, f, first, val;
714 793
715 *portp = 0; 794 dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
716 addr_len = ntohl(*p++); 795 task->tk_pid, task->tk_msg.rpc_proc->p_name,
796 rpcb->r_prog, rpcb->r_vers,
797 rpcb->r_netid, rpcb->r_addr);
717 798
718 if (addr_len == 0) { 799 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
719 dprintk("RPC: rpcb_decode_getaddr: "
720 "service is not registered\n");
721 return 0;
722 }
723 800
724 /* 801 p = xdr_reserve_space(&xdr,
725 * Simple sanity check. 802 sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz));
726 */ 803 if (unlikely(p == NULL))
727 if (addr_len > RPCBIND_MAXUADDRLEN) 804 return -EIO;
728 goto out_err; 805 *p++ = htonl(rpcb->r_prog);
729 806 *p = htonl(rpcb->r_vers);
730 /*
731 * Start at the end and walk backwards until the first dot
732 * is encountered. When the second dot is found, we have
733 * both parts of the port number.
734 */
735 addr = (char *)p;
736 val = 0;
737 first = 1;
738 f = 1;
739 for (i = addr_len - 1; i > 0; i--) {
740 c = addr[i];
741 if (c >= '0' && c <= '9') {
742 val += (c - '0') * f;
743 f *= 10;
744 } else if (c == '.') {
745 if (first) {
746 *portp = val;
747 val = first = 0;
748 f = 1;
749 } else {
750 *portp |= (val << 8);
751 break;
752 }
753 }
754 }
755 807
756 /* 808 if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN))
757 * Simple sanity check. If we never saw a dot in the reply, 809 return -EIO;
758 * then this was probably just garbage. 810 if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN))
759 */ 811 return -EIO;
760 if (first) 812 if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN))
761 goto out_err; 813 return -EIO;
762 814
763 dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp);
764 return 0; 815 return 0;
765
766out_err:
767 dprintk("RPC: rpcbind server returned malformed reply\n");
768 return -EIO;
769} 816}
770 817
771#define RPCB_program_sz (1u) 818static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p,
772#define RPCB_version_sz (1u) 819 struct rpcbind_args *rpcb)
773#define RPCB_protocol_sz (1u) 820{
774#define RPCB_port_sz (1u) 821 struct sockaddr_storage address;
775#define RPCB_boolean_sz (1u) 822 struct sockaddr *sap = (struct sockaddr *)&address;
823 struct rpc_task *task = req->rq_task;
824 struct xdr_stream xdr;
825 u32 len;
776 826
777#define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN)) 827 rpcb->r_port = 0;
778#define RPCB_addr_sz (1+XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
779#define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN))
780 828
781#define RPCB_mappingargs_sz RPCB_program_sz+RPCB_version_sz+ \ 829 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
782 RPCB_protocol_sz+RPCB_port_sz
783#define RPCB_getaddrargs_sz RPCB_program_sz+RPCB_version_sz+ \
784 RPCB_netid_sz+RPCB_addr_sz+ \
785 RPCB_ownerstring_sz
786 830
787#define RPCB_setres_sz RPCB_boolean_sz 831 p = xdr_inline_decode(&xdr, sizeof(__be32));
788#define RPCB_getportres_sz RPCB_port_sz 832 if (unlikely(p == NULL))
789 833 goto out_fail;
790/* 834 len = ntohl(*p);
791 * Note that RFC 1833 does not put any size restrictions on the
792 * address string returned by the remote rpcbind database.
793 */
794#define RPCB_getaddrres_sz RPCB_addr_sz
795 835
796#define PROC(proc, argtype, restype) \ 836 /*
797 [RPCBPROC_##proc] = { \ 837 * If the returned universal address is a null string,
798 .p_proc = RPCBPROC_##proc, \ 838 * the requested RPC service was not registered.
799 .p_encode = (kxdrproc_t) rpcb_encode_##argtype, \ 839 */
800 .p_decode = (kxdrproc_t) rpcb_decode_##restype, \ 840 if (len == 0) {
801 .p_arglen = RPCB_##argtype##args_sz, \ 841 dprintk("RPC: %5u RPCB reply: program not registered\n",
802 .p_replen = RPCB_##restype##res_sz, \ 842 task->tk_pid);
803 .p_statidx = RPCBPROC_##proc, \ 843 return 0;
804 .p_timer = 0, \
805 .p_name = #proc, \
806 } 844 }
807 845
846 if (unlikely(len > RPCBIND_MAXUADDRLEN))
847 goto out_fail;
848
849 p = xdr_inline_decode(&xdr, len);
850 if (unlikely(p == NULL))
851 goto out_fail;
852 dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
853 task->tk_msg.rpc_proc->p_name, (char *)p);
854
855 if (rpc_uaddr2sockaddr((char *)p, len, sap, sizeof(address)) == 0)
856 goto out_fail;
857 rpcb->r_port = rpc_get_port(sap);
858
859 return 0;
860
861out_fail:
862 dprintk("RPC: %5u malformed RPCB_%s reply\n",
863 task->tk_pid, task->tk_msg.rpc_proc->p_name);
864 return -EIO;
865}
866
808/* 867/*
809 * Not all rpcbind procedures described in RFC 1833 are implemented 868 * Not all rpcbind procedures described in RFC 1833 are implemented
810 * since the Linux kernel RPC code requires only these. 869 * since the Linux kernel RPC code requires only these.
811 */ 870 */
871
812static struct rpc_procinfo rpcb_procedures2[] = { 872static struct rpc_procinfo rpcb_procedures2[] = {
813 PROC(SET, mapping, set), 873 [RPCBPROC_SET] = {
814 PROC(UNSET, mapping, set), 874 .p_proc = RPCBPROC_SET,
815 PROC(GETPORT, mapping, getport), 875 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
876 .p_decode = (kxdrproc_t)rpcb_dec_set,
877 .p_arglen = RPCB_mappingargs_sz,
878 .p_replen = RPCB_setres_sz,
879 .p_statidx = RPCBPROC_SET,
880 .p_timer = 0,
881 .p_name = "SET",
882 },
883 [RPCBPROC_UNSET] = {
884 .p_proc = RPCBPROC_UNSET,
885 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
886 .p_decode = (kxdrproc_t)rpcb_dec_set,
887 .p_arglen = RPCB_mappingargs_sz,
888 .p_replen = RPCB_setres_sz,
889 .p_statidx = RPCBPROC_UNSET,
890 .p_timer = 0,
891 .p_name = "UNSET",
892 },
893 [RPCBPROC_GETPORT] = {
894 .p_proc = RPCBPROC_GETPORT,
895 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
896 .p_decode = (kxdrproc_t)rpcb_dec_getport,
897 .p_arglen = RPCB_mappingargs_sz,
898 .p_replen = RPCB_getportres_sz,
899 .p_statidx = RPCBPROC_GETPORT,
900 .p_timer = 0,
901 .p_name = "GETPORT",
902 },
816}; 903};
817 904
818static struct rpc_procinfo rpcb_procedures3[] = { 905static struct rpc_procinfo rpcb_procedures3[] = {
819 PROC(SET, getaddr, set), 906 [RPCBPROC_SET] = {
820 PROC(UNSET, getaddr, set), 907 .p_proc = RPCBPROC_SET,
821 PROC(GETADDR, getaddr, getaddr), 908 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
909 .p_decode = (kxdrproc_t)rpcb_dec_set,
910 .p_arglen = RPCB_getaddrargs_sz,
911 .p_replen = RPCB_setres_sz,
912 .p_statidx = RPCBPROC_SET,
913 .p_timer = 0,
914 .p_name = "SET",
915 },
916 [RPCBPROC_UNSET] = {
917 .p_proc = RPCBPROC_UNSET,
918 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
919 .p_decode = (kxdrproc_t)rpcb_dec_set,
920 .p_arglen = RPCB_getaddrargs_sz,
921 .p_replen = RPCB_setres_sz,
922 .p_statidx = RPCBPROC_UNSET,
923 .p_timer = 0,
924 .p_name = "UNSET",
925 },
926 [RPCBPROC_GETADDR] = {
927 .p_proc = RPCBPROC_GETADDR,
928 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
929 .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
930 .p_arglen = RPCB_getaddrargs_sz,
931 .p_replen = RPCB_getaddrres_sz,
932 .p_statidx = RPCBPROC_GETADDR,
933 .p_timer = 0,
934 .p_name = "GETADDR",
935 },
822}; 936};
823 937
824static struct rpc_procinfo rpcb_procedures4[] = { 938static struct rpc_procinfo rpcb_procedures4[] = {
825 PROC(SET, getaddr, set), 939 [RPCBPROC_SET] = {
826 PROC(UNSET, getaddr, set), 940 .p_proc = RPCBPROC_SET,
827 PROC(GETADDR, getaddr, getaddr), 941 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
828 PROC(GETVERSADDR, getaddr, getaddr), 942 .p_decode = (kxdrproc_t)rpcb_dec_set,
943 .p_arglen = RPCB_getaddrargs_sz,
944 .p_replen = RPCB_setres_sz,
945 .p_statidx = RPCBPROC_SET,
946 .p_timer = 0,
947 .p_name = "SET",
948 },
949 [RPCBPROC_UNSET] = {
950 .p_proc = RPCBPROC_UNSET,
951 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
952 .p_decode = (kxdrproc_t)rpcb_dec_set,
953 .p_arglen = RPCB_getaddrargs_sz,
954 .p_replen = RPCB_setres_sz,
955 .p_statidx = RPCBPROC_UNSET,
956 .p_timer = 0,
957 .p_name = "UNSET",
958 },
959 [RPCBPROC_GETADDR] = {
960 .p_proc = RPCBPROC_GETADDR,
961 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
962 .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
963 .p_arglen = RPCB_getaddrargs_sz,
964 .p_replen = RPCB_getaddrres_sz,
965 .p_statidx = RPCBPROC_GETADDR,
966 .p_timer = 0,
967 .p_name = "GETADDR",
968 },
829}; 969};
830 970
831static struct rpcb_info rpcb_next_version[] = { 971static struct rpcb_info rpcb_next_version[] = {
diff --git a/net/sunrpc/timer.c b/net/sunrpc/timer.c
index 31becbf09263..dd824341c349 100644
--- a/net/sunrpc/timer.c
+++ b/net/sunrpc/timer.c
@@ -25,8 +25,13 @@
25#define RPC_RTO_INIT (HZ/5) 25#define RPC_RTO_INIT (HZ/5)
26#define RPC_RTO_MIN (HZ/10) 26#define RPC_RTO_MIN (HZ/10)
27 27
28void 28/**
29rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo) 29 * rpc_init_rtt - Initialize an RPC RTT estimator context
30 * @rt: context to initialize
31 * @timeo: initial timeout value, in jiffies
32 *
33 */
34void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
30{ 35{
31 unsigned long init = 0; 36 unsigned long init = 0;
32 unsigned i; 37 unsigned i;
@@ -43,12 +48,16 @@ rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
43} 48}
44EXPORT_SYMBOL_GPL(rpc_init_rtt); 49EXPORT_SYMBOL_GPL(rpc_init_rtt);
45 50
46/* 51/**
52 * rpc_update_rtt - Update an RPC RTT estimator context
53 * @rt: context to update
54 * @timer: timer array index (request type)
55 * @m: recent actual RTT, in jiffies
56 *
47 * NB: When computing the smoothed RTT and standard deviation, 57 * NB: When computing the smoothed RTT and standard deviation,
48 * be careful not to produce negative intermediate results. 58 * be careful not to produce negative intermediate results.
49 */ 59 */
50void 60void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
51rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
52{ 61{
53 long *srtt, *sdrtt; 62 long *srtt, *sdrtt;
54 63
@@ -79,21 +88,25 @@ rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
79} 88}
80EXPORT_SYMBOL_GPL(rpc_update_rtt); 89EXPORT_SYMBOL_GPL(rpc_update_rtt);
81 90
82/* 91/**
83 * Estimate rto for an nfs rpc sent via. an unreliable datagram. 92 * rpc_calc_rto - Provide an estimated timeout value
84 * Use the mean and mean deviation of rtt for the appropriate type of rpc 93 * @rt: context to use for calculation
85 * for the frequent rpcs and a default for the others. 94 * @timer: timer array index (request type)
86 * The justification for doing "other" this way is that these rpcs 95 *
87 * happen so infrequently that timer est. would probably be stale. 96 * Estimate RTO for an NFS RPC sent via an unreliable datagram. Use
88 * Also, since many of these rpcs are 97 * the mean and mean deviation of RTT for the appropriate type of RPC
89 * non-idempotent, a conservative timeout is desired. 98 * for frequently issued RPCs, and a fixed default for the others.
99 *
100 * The justification for doing "other" this way is that these RPCs
101 * happen so infrequently that timer estimation would probably be
102 * stale. Also, since many of these RPCs are non-idempotent, a
103 * conservative timeout is desired.
104 *
90 * getattr, lookup, 105 * getattr, lookup,
91 * read, write, commit - A+4D 106 * read, write, commit - A+4D
92 * other - timeo 107 * other - timeo
93 */ 108 */
94 109unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
95unsigned long
96rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
97{ 110{
98 unsigned long res; 111 unsigned long res;
99 112
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 1dd6123070e9..9a63f669ece4 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -168,47 +168,25 @@ static struct rpc_xprt_ops xprt_rdma_procs; /* forward reference */
168static void 168static void
169xprt_rdma_format_addresses(struct rpc_xprt *xprt) 169xprt_rdma_format_addresses(struct rpc_xprt *xprt)
170{ 170{
171 struct sockaddr_in *addr = (struct sockaddr_in *) 171 struct sockaddr *sap = (struct sockaddr *)
172 &rpcx_to_rdmad(xprt).addr; 172 &rpcx_to_rdmad(xprt).addr;
173 char *buf; 173 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
174 char buf[64];
174 175
175 buf = kzalloc(20, GFP_KERNEL); 176 (void)rpc_ntop(sap, buf, sizeof(buf));
176 if (buf) 177 xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL);
177 snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
178 xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
179 178
180 buf = kzalloc(8, GFP_KERNEL); 179 (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
181 if (buf) 180 xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
182 snprintf(buf, 8, "%u", ntohs(addr->sin_port));
183 xprt->address_strings[RPC_DISPLAY_PORT] = buf;
184 181
185 xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma"; 182 xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma";
186 183
187 buf = kzalloc(48, GFP_KERNEL); 184 (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
188 if (buf) 185 NIPQUAD(sin->sin_addr.s_addr));
189 snprintf(buf, 48, "addr=%pI4 port=%u proto=%s", 186 xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
190 &addr->sin_addr.s_addr, 187
191 ntohs(addr->sin_port), "rdma"); 188 (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
192 xprt->address_strings[RPC_DISPLAY_ALL] = buf; 189 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
193
194 buf = kzalloc(10, GFP_KERNEL);
195 if (buf)
196 snprintf(buf, 10, "%02x%02x%02x%02x",
197 NIPQUAD(addr->sin_addr.s_addr));
198 xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
199
200 buf = kzalloc(8, GFP_KERNEL);
201 if (buf)
202 snprintf(buf, 8, "%4hx", ntohs(addr->sin_port));
203 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
204
205 buf = kzalloc(30, GFP_KERNEL);
206 if (buf)
207 snprintf(buf, 30, "%pI4.%u.%u",
208 &addr->sin_addr.s_addr,
209 ntohs(addr->sin_port) >> 8,
210 ntohs(addr->sin_port) & 0xff);
211 xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
212 190
213 /* netid */ 191 /* netid */
214 xprt->address_strings[RPC_DISPLAY_NETID] = "rdma"; 192 xprt->address_strings[RPC_DISPLAY_NETID] = "rdma";
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 585a864c1c4c..62438f3a914d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -248,8 +248,8 @@ struct sock_xprt {
248 * Connection of transports 248 * Connection of transports
249 */ 249 */
250 struct delayed_work connect_worker; 250 struct delayed_work connect_worker;
251 struct sockaddr_storage addr; 251 struct sockaddr_storage srcaddr;
252 unsigned short port; 252 unsigned short srcport;
253 253
254 /* 254 /*
255 * UDP socket buffer size parameters 255 * UDP socket buffer size parameters
@@ -296,117 +296,60 @@ static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt)
296 return (struct sockaddr_in6 *) &xprt->addr; 296 return (struct sockaddr_in6 *) &xprt->addr;
297} 297}
298 298
299static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt, 299static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
300 const char *protocol,
301 const char *netid)
302{ 300{
303 struct sockaddr_in *addr = xs_addr_in(xprt); 301 struct sockaddr *sap = xs_addr(xprt);
304 char *buf; 302 struct sockaddr_in6 *sin6;
303 struct sockaddr_in *sin;
304 char buf[128];
305 305
306 buf = kzalloc(20, GFP_KERNEL); 306 (void)rpc_ntop(sap, buf, sizeof(buf));
307 if (buf) { 307 xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL);
308 snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
309 }
310 xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
311
312 buf = kzalloc(8, GFP_KERNEL);
313 if (buf) {
314 snprintf(buf, 8, "%u",
315 ntohs(addr->sin_port));
316 }
317 xprt->address_strings[RPC_DISPLAY_PORT] = buf;
318
319 xprt->address_strings[RPC_DISPLAY_PROTO] = protocol;
320
321 buf = kzalloc(48, GFP_KERNEL);
322 if (buf) {
323 snprintf(buf, 48, "addr=%pI4 port=%u proto=%s",
324 &addr->sin_addr.s_addr,
325 ntohs(addr->sin_port),
326 protocol);
327 }
328 xprt->address_strings[RPC_DISPLAY_ALL] = buf;
329
330 buf = kzalloc(10, GFP_KERNEL);
331 if (buf) {
332 snprintf(buf, 10, "%02x%02x%02x%02x",
333 NIPQUAD(addr->sin_addr.s_addr));
334 }
335 xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
336 308
337 buf = kzalloc(8, GFP_KERNEL); 309 switch (sap->sa_family) {
338 if (buf) { 310 case AF_INET:
339 snprintf(buf, 8, "%4hx", 311 sin = xs_addr_in(xprt);
340 ntohs(addr->sin_port)); 312 (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
341 } 313 NIPQUAD(sin->sin_addr.s_addr));
342 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; 314 break;
343 315 case AF_INET6:
344 buf = kzalloc(30, GFP_KERNEL); 316 sin6 = xs_addr_in6(xprt);
345 if (buf) { 317 (void)snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
346 snprintf(buf, 30, "%pI4.%u.%u", 318 break;
347 &addr->sin_addr.s_addr, 319 default:
348 ntohs(addr->sin_port) >> 8, 320 BUG();
349 ntohs(addr->sin_port) & 0xff);
350 } 321 }
351 xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; 322 xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
352
353 xprt->address_strings[RPC_DISPLAY_NETID] = netid;
354} 323}
355 324
356static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt, 325static void xs_format_common_peer_ports(struct rpc_xprt *xprt)
357 const char *protocol,
358 const char *netid)
359{ 326{
360 struct sockaddr_in6 *addr = xs_addr_in6(xprt); 327 struct sockaddr *sap = xs_addr(xprt);
361 char *buf; 328 char buf[128];
362 329
363 buf = kzalloc(40, GFP_KERNEL); 330 (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
364 if (buf) { 331 xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
365 snprintf(buf, 40, "%pI6",&addr->sin6_addr);
366 }
367 xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
368 332
369 buf = kzalloc(8, GFP_KERNEL); 333 (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
370 if (buf) { 334 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
371 snprintf(buf, 8, "%u", 335}
372 ntohs(addr->sin6_port));
373 }
374 xprt->address_strings[RPC_DISPLAY_PORT] = buf;
375 336
337static void xs_format_peer_addresses(struct rpc_xprt *xprt,
338 const char *protocol,
339 const char *netid)
340{
376 xprt->address_strings[RPC_DISPLAY_PROTO] = protocol; 341 xprt->address_strings[RPC_DISPLAY_PROTO] = protocol;
342 xprt->address_strings[RPC_DISPLAY_NETID] = netid;
343 xs_format_common_peer_addresses(xprt);
344 xs_format_common_peer_ports(xprt);
345}
377 346
378 buf = kzalloc(64, GFP_KERNEL); 347static void xs_update_peer_port(struct rpc_xprt *xprt)
379 if (buf) { 348{
380 snprintf(buf, 64, "addr=%pI6 port=%u proto=%s", 349 kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);
381 &addr->sin6_addr, 350 kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
382 ntohs(addr->sin6_port),
383 protocol);
384 }
385 xprt->address_strings[RPC_DISPLAY_ALL] = buf;
386
387 buf = kzalloc(36, GFP_KERNEL);
388 if (buf)
389 snprintf(buf, 36, "%pi6", &addr->sin6_addr);
390
391 xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
392
393 buf = kzalloc(8, GFP_KERNEL);
394 if (buf) {
395 snprintf(buf, 8, "%4hx",
396 ntohs(addr->sin6_port));
397 }
398 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
399
400 buf = kzalloc(50, GFP_KERNEL);
401 if (buf) {
402 snprintf(buf, 50, "%pI6.%u.%u",
403 &addr->sin6_addr,
404 ntohs(addr->sin6_port) >> 8,
405 ntohs(addr->sin6_port) & 0xff);
406 }
407 xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
408 351
409 xprt->address_strings[RPC_DISPLAY_NETID] = netid; 352 xs_format_common_peer_ports(xprt);
410} 353}
411 354
412static void xs_free_peer_addresses(struct rpc_xprt *xprt) 355static void xs_free_peer_addresses(struct rpc_xprt *xprt)
@@ -1587,25 +1530,15 @@ static unsigned short xs_get_random_port(void)
1587 */ 1530 */
1588static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) 1531static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
1589{ 1532{
1590 struct sockaddr *addr = xs_addr(xprt);
1591
1592 dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); 1533 dprintk("RPC: setting port for xprt %p to %u\n", xprt, port);
1593 1534
1594 switch (addr->sa_family) { 1535 rpc_set_port(xs_addr(xprt), port);
1595 case AF_INET: 1536 xs_update_peer_port(xprt);
1596 ((struct sockaddr_in *)addr)->sin_port = htons(port);
1597 break;
1598 case AF_INET6:
1599 ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
1600 break;
1601 default:
1602 BUG();
1603 }
1604} 1537}
1605 1538
1606static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock) 1539static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock)
1607{ 1540{
1608 unsigned short port = transport->port; 1541 unsigned short port = transport->srcport;
1609 1542
1610 if (port == 0 && transport->xprt.resvport) 1543 if (port == 0 && transport->xprt.resvport)
1611 port = xs_get_random_port(); 1544 port = xs_get_random_port();
@@ -1614,8 +1547,8 @@ static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket
1614 1547
1615static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket *sock, unsigned short port) 1548static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket *sock, unsigned short port)
1616{ 1549{
1617 if (transport->port != 0) 1550 if (transport->srcport != 0)
1618 transport->port = 0; 1551 transport->srcport = 0;
1619 if (!transport->xprt.resvport) 1552 if (!transport->xprt.resvport)
1620 return 0; 1553 return 0;
1621 if (port <= xprt_min_resvport || port > xprt_max_resvport) 1554 if (port <= xprt_min_resvport || port > xprt_max_resvport)
@@ -1633,7 +1566,7 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
1633 unsigned short port = xs_get_srcport(transport, sock); 1566 unsigned short port = xs_get_srcport(transport, sock);
1634 unsigned short last; 1567 unsigned short last;
1635 1568
1636 sa = (struct sockaddr_in *)&transport->addr; 1569 sa = (struct sockaddr_in *)&transport->srcaddr;
1637 myaddr.sin_addr = sa->sin_addr; 1570 myaddr.sin_addr = sa->sin_addr;
1638 do { 1571 do {
1639 myaddr.sin_port = htons(port); 1572 myaddr.sin_port = htons(port);
@@ -1642,7 +1575,7 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
1642 if (port == 0) 1575 if (port == 0)
1643 break; 1576 break;
1644 if (err == 0) { 1577 if (err == 0) {
1645 transport->port = port; 1578 transport->srcport = port;
1646 break; 1579 break;
1647 } 1580 }
1648 last = port; 1581 last = port;
@@ -1666,7 +1599,7 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
1666 unsigned short port = xs_get_srcport(transport, sock); 1599 unsigned short port = xs_get_srcport(transport, sock);
1667 unsigned short last; 1600 unsigned short last;
1668 1601
1669 sa = (struct sockaddr_in6 *)&transport->addr; 1602 sa = (struct sockaddr_in6 *)&transport->srcaddr;
1670 myaddr.sin6_addr = sa->sin6_addr; 1603 myaddr.sin6_addr = sa->sin6_addr;
1671 do { 1604 do {
1672 myaddr.sin6_port = htons(port); 1605 myaddr.sin6_port = htons(port);
@@ -1675,7 +1608,7 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
1675 if (port == 0) 1608 if (port == 0)
1676 break; 1609 break;
1677 if (err == 0) { 1610 if (err == 0) {
1678 transport->port = port; 1611 transport->srcport = port;
1679 break; 1612 break;
1680 } 1613 }
1681 last = port; 1614 last = port;
@@ -1780,8 +1713,11 @@ static void xs_udp_connect_worker4(struct work_struct *work)
1780 goto out; 1713 goto out;
1781 } 1714 }
1782 1715
1783 dprintk("RPC: worker connecting xprt %p to address: %s\n", 1716 dprintk("RPC: worker connecting xprt %p via %s to "
1784 xprt, xprt->address_strings[RPC_DISPLAY_ALL]); 1717 "%s (port %s)\n", xprt,
1718 xprt->address_strings[RPC_DISPLAY_PROTO],
1719 xprt->address_strings[RPC_DISPLAY_ADDR],
1720 xprt->address_strings[RPC_DISPLAY_PORT]);
1785 1721
1786 xs_udp_finish_connecting(xprt, sock); 1722 xs_udp_finish_connecting(xprt, sock);
1787 status = 0; 1723 status = 0;
@@ -1822,8 +1758,11 @@ static void xs_udp_connect_worker6(struct work_struct *work)
1822 goto out; 1758 goto out;
1823 } 1759 }
1824 1760
1825 dprintk("RPC: worker connecting xprt %p to address: %s\n", 1761 dprintk("RPC: worker connecting xprt %p via %s to "
1826 xprt, xprt->address_strings[RPC_DISPLAY_ALL]); 1762 "%s (port %s)\n", xprt,
1763 xprt->address_strings[RPC_DISPLAY_PROTO],
1764 xprt->address_strings[RPC_DISPLAY_ADDR],
1765 xprt->address_strings[RPC_DISPLAY_PORT]);
1827 1766
1828 xs_udp_finish_connecting(xprt, sock); 1767 xs_udp_finish_connecting(xprt, sock);
1829 status = 0; 1768 status = 0;
@@ -1948,8 +1887,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
1948 goto out_eagain; 1887 goto out_eagain;
1949 } 1888 }
1950 1889
1951 dprintk("RPC: worker connecting xprt %p to address: %s\n", 1890 dprintk("RPC: worker connecting xprt %p via %s to "
1952 xprt, xprt->address_strings[RPC_DISPLAY_ALL]); 1891 "%s (port %s)\n", xprt,
1892 xprt->address_strings[RPC_DISPLAY_PROTO],
1893 xprt->address_strings[RPC_DISPLAY_ADDR],
1894 xprt->address_strings[RPC_DISPLAY_PORT]);
1953 1895
1954 status = xs_tcp_finish_connecting(xprt, sock); 1896 status = xs_tcp_finish_connecting(xprt, sock);
1955 dprintk("RPC: %p connect status %d connected %d sock state %d\n", 1897 dprintk("RPC: %p connect status %d connected %d sock state %d\n",
@@ -2120,7 +2062,7 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
2120 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 2062 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
2121 2063
2122 seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", 2064 seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
2123 transport->port, 2065 transport->srcport,
2124 xprt->stat.bind_count, 2066 xprt->stat.bind_count,
2125 xprt->stat.sends, 2067 xprt->stat.sends,
2126 xprt->stat.recvs, 2068 xprt->stat.recvs,
@@ -2144,7 +2086,7 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
2144 idle_time = (long)(jiffies - xprt->last_used) / HZ; 2086 idle_time = (long)(jiffies - xprt->last_used) / HZ;
2145 2087
2146 seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", 2088 seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
2147 transport->port, 2089 transport->srcport,
2148 xprt->stat.bind_count, 2090 xprt->stat.bind_count,
2149 xprt->stat.connect_count, 2091 xprt->stat.connect_count,
2150 xprt->stat.connect_time, 2092 xprt->stat.connect_time,
@@ -2223,7 +2165,7 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
2223 memcpy(&xprt->addr, args->dstaddr, args->addrlen); 2165 memcpy(&xprt->addr, args->dstaddr, args->addrlen);
2224 xprt->addrlen = args->addrlen; 2166 xprt->addrlen = args->addrlen;
2225 if (args->srcaddr) 2167 if (args->srcaddr)
2226 memcpy(&new->addr, args->srcaddr, args->addrlen); 2168 memcpy(&new->srcaddr, args->srcaddr, args->addrlen);
2227 2169
2228 return xprt; 2170 return xprt;
2229} 2171}
@@ -2272,7 +2214,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
2272 2214
2273 INIT_DELAYED_WORK(&transport->connect_worker, 2215 INIT_DELAYED_WORK(&transport->connect_worker,
2274 xs_udp_connect_worker4); 2216 xs_udp_connect_worker4);
2275 xs_format_ipv4_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP); 2217 xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP);
2276 break; 2218 break;
2277 case AF_INET6: 2219 case AF_INET6:
2278 if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) 2220 if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
@@ -2280,15 +2222,22 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
2280 2222
2281 INIT_DELAYED_WORK(&transport->connect_worker, 2223 INIT_DELAYED_WORK(&transport->connect_worker,
2282 xs_udp_connect_worker6); 2224 xs_udp_connect_worker6);
2283 xs_format_ipv6_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6); 2225 xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6);
2284 break; 2226 break;
2285 default: 2227 default:
2286 kfree(xprt); 2228 kfree(xprt);
2287 return ERR_PTR(-EAFNOSUPPORT); 2229 return ERR_PTR(-EAFNOSUPPORT);
2288 } 2230 }
2289 2231
2290 dprintk("RPC: set up transport to address %s\n", 2232 if (xprt_bound(xprt))
2291 xprt->address_strings[RPC_DISPLAY_ALL]); 2233 dprintk("RPC: set up xprt to %s (port %s) via %s\n",
2234 xprt->address_strings[RPC_DISPLAY_ADDR],
2235 xprt->address_strings[RPC_DISPLAY_PORT],
2236 xprt->address_strings[RPC_DISPLAY_PROTO]);
2237 else
2238 dprintk("RPC: set up xprt to %s (autobind) via %s\n",
2239 xprt->address_strings[RPC_DISPLAY_ADDR],
2240 xprt->address_strings[RPC_DISPLAY_PROTO]);
2292 2241
2293 if (try_module_get(THIS_MODULE)) 2242 if (try_module_get(THIS_MODULE))
2294 return xprt; 2243 return xprt;
@@ -2337,23 +2286,33 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
2337 if (((struct sockaddr_in *)addr)->sin_port != htons(0)) 2286 if (((struct sockaddr_in *)addr)->sin_port != htons(0))
2338 xprt_set_bound(xprt); 2287 xprt_set_bound(xprt);
2339 2288
2340 INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); 2289 INIT_DELAYED_WORK(&transport->connect_worker,
2341 xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP); 2290 xs_tcp_connect_worker4);
2291 xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
2342 break; 2292 break;
2343 case AF_INET6: 2293 case AF_INET6:
2344 if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) 2294 if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
2345 xprt_set_bound(xprt); 2295 xprt_set_bound(xprt);
2346 2296
2347 INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); 2297 INIT_DELAYED_WORK(&transport->connect_worker,
2348 xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6); 2298 xs_tcp_connect_worker6);
2299 xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
2349 break; 2300 break;
2350 default: 2301 default:
2351 kfree(xprt); 2302 kfree(xprt);
2352 return ERR_PTR(-EAFNOSUPPORT); 2303 return ERR_PTR(-EAFNOSUPPORT);
2353 } 2304 }
2354 2305
2355 dprintk("RPC: set up transport to address %s\n", 2306 if (xprt_bound(xprt))
2356 xprt->address_strings[RPC_DISPLAY_ALL]); 2307 dprintk("RPC: set up xprt to %s (port %s) via %s\n",
2308 xprt->address_strings[RPC_DISPLAY_ADDR],
2309 xprt->address_strings[RPC_DISPLAY_PORT],
2310 xprt->address_strings[RPC_DISPLAY_PROTO]);
2311 else
2312 dprintk("RPC: set up xprt to %s (autobind) via %s\n",
2313 xprt->address_strings[RPC_DISPLAY_ADDR],
2314 xprt->address_strings[RPC_DISPLAY_PROTO]);
2315
2357 2316
2358 if (try_module_get(THIS_MODULE)) 2317 if (try_module_get(THIS_MODULE))
2359 return xprt; 2318 return xprt;