aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/svc_xprt.h51
-rw-r--r--include/linux/sunrpc/svcsock.h4
-rw-r--r--net/sunrpc/svc_xprt.c31
-rw-r--r--net/sunrpc/svcsock.c56
4 files changed, 110 insertions, 32 deletions
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 6a8445b9dfd9..09de12b63c1d 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -61,6 +61,10 @@ struct svc_xprt {
61 void *xpt_auth_cache;/* auth cache */ 61 void *xpt_auth_cache;/* auth cache */
62 struct list_head xpt_deferred; /* deferred requests that need 62 struct list_head xpt_deferred; /* deferred requests that need
63 * to be revisted */ 63 * to be revisted */
64 struct sockaddr_storage xpt_local; /* local address */
65 size_t xpt_locallen; /* length of address */
66 struct sockaddr_storage xpt_remote; /* remote peer's address */
67 size_t xpt_remotelen; /* length of address */
64}; 68};
65 69
66int svc_reg_xprt_class(struct svc_xprt_class *); 70int svc_reg_xprt_class(struct svc_xprt_class *);
@@ -70,9 +74,56 @@ void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *,
70int svc_create_xprt(struct svc_serv *, char *, unsigned short, int); 74int svc_create_xprt(struct svc_serv *, char *, unsigned short, int);
71void svc_xprt_received(struct svc_xprt *); 75void svc_xprt_received(struct svc_xprt *);
72void svc_xprt_put(struct svc_xprt *xprt); 76void svc_xprt_put(struct svc_xprt *xprt);
77void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
73static inline void svc_xprt_get(struct svc_xprt *xprt) 78static inline void svc_xprt_get(struct svc_xprt *xprt)
74{ 79{
75 kref_get(&xprt->xpt_ref); 80 kref_get(&xprt->xpt_ref);
76} 81}
82static inline void svc_xprt_set_local(struct svc_xprt *xprt,
83 struct sockaddr *sa, int salen)
84{
85 memcpy(&xprt->xpt_local, sa, salen);
86 xprt->xpt_locallen = salen;
87}
88static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
89 struct sockaddr *sa, int salen)
90{
91 memcpy(&xprt->xpt_remote, sa, salen);
92 xprt->xpt_remotelen = salen;
93}
94static inline unsigned short svc_addr_port(struct sockaddr *sa)
95{
96 unsigned short ret = 0;
97 switch (sa->sa_family) {
98 case AF_INET:
99 ret = ntohs(((struct sockaddr_in *)sa)->sin_port);
100 break;
101 case AF_INET6:
102 ret = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
103 break;
104 }
105 return ret;
106}
107
108static inline size_t svc_addr_len(struct sockaddr *sa)
109{
110 switch (sa->sa_family) {
111 case AF_INET:
112 return sizeof(struct sockaddr_in);
113 case AF_INET6:
114 return sizeof(struct sockaddr_in6);
115 }
116 return -EAFNOSUPPORT;
117}
118
119static inline unsigned short svc_xprt_local_port(struct svc_xprt *xprt)
120{
121 return svc_addr_port((struct sockaddr *)&xprt->xpt_local);
122}
123
124static inline unsigned short svc_xprt_remote_port(struct svc_xprt *xprt)
125{
126 return svc_addr_port((struct sockaddr *)&xprt->xpt_remote);
127}
77 128
78#endif /* SUNRPC_SVC_XPRT_H */ 129#endif /* SUNRPC_SVC_XPRT_H */
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 96a229e6b9c9..206f092ad4c7 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -28,10 +28,6 @@ struct svc_sock {
28 /* private TCP part */ 28 /* private TCP part */
29 int sk_reclen; /* length of record */ 29 int sk_reclen; /* length of record */
30 int sk_tcplen; /* current read length */ 30 int sk_tcplen; /* current read length */
31
32 struct sockaddr_storage sk_local; /* local address */
33 struct sockaddr_storage sk_remote; /* remote peer's address */
34 int sk_remotelen; /* length of address */
35}; 31};
36 32
37/* 33/*
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 023aeb0ecfa9..eb650af50c49 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -125,7 +125,6 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
125 spin_unlock(&svc_xprt_class_lock); 125 spin_unlock(&svc_xprt_class_lock);
126 if (try_module_get(xcl->xcl_owner)) { 126 if (try_module_get(xcl->xcl_owner)) {
127 struct svc_xprt *newxprt; 127 struct svc_xprt *newxprt;
128 ret = 0;
129 newxprt = xcl->xcl_ops->xpo_create 128 newxprt = xcl->xcl_ops->xpo_create
130 (serv, 129 (serv,
131 (struct sockaddr *)&sin, sizeof(sin), 130 (struct sockaddr *)&sin, sizeof(sin),
@@ -133,7 +132,8 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
133 if (IS_ERR(newxprt)) { 132 if (IS_ERR(newxprt)) {
134 module_put(xcl->xcl_owner); 133 module_put(xcl->xcl_owner);
135 ret = PTR_ERR(newxprt); 134 ret = PTR_ERR(newxprt);
136 } 135 } else
136 ret = svc_xprt_local_port(newxprt);
137 } 137 }
138 goto out; 138 goto out;
139 } 139 }
@@ -144,3 +144,30 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
144 return ret; 144 return ret;
145} 145}
146EXPORT_SYMBOL_GPL(svc_create_xprt); 146EXPORT_SYMBOL_GPL(svc_create_xprt);
147
148/*
149 * Copy the local and remote xprt addresses to the rqstp structure
150 */
151void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt)
152{
153 struct sockaddr *sin;
154
155 memcpy(&rqstp->rq_addr, &xprt->xpt_remote, xprt->xpt_remotelen);
156 rqstp->rq_addrlen = xprt->xpt_remotelen;
157
158 /*
159 * Destination address in request is needed for binding the
160 * source address in RPC replies/callbacks later.
161 */
162 sin = (struct sockaddr *)&xprt->xpt_local;
163 switch (sin->sa_family) {
164 case AF_INET:
165 rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
166 break;
167 case AF_INET6:
168 rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
169 break;
170 }
171}
172EXPORT_SYMBOL_GPL(svc_xprt_copy_addrs);
173
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 9d0a9e6c0e10..9564d2e9520e 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -623,33 +623,13 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
623 struct msghdr msg = { 623 struct msghdr msg = {
624 .msg_flags = MSG_DONTWAIT, 624 .msg_flags = MSG_DONTWAIT,
625 }; 625 };
626 struct sockaddr *sin;
627 int len; 626 int len;
628 627
629 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, 628 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
630 msg.msg_flags); 629 msg.msg_flags);
631 630
632 /* sock_recvmsg doesn't fill in the name/namelen, so we must..
633 */
634 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen);
635 rqstp->rq_addrlen = svsk->sk_remotelen;
636
637 /* Destination address in request is needed for binding the
638 * source address in RPC callbacks later.
639 */
640 sin = (struct sockaddr *)&svsk->sk_local;
641 switch (sin->sa_family) {
642 case AF_INET:
643 rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
644 break;
645 case AF_INET6:
646 rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
647 break;
648 }
649
650 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", 631 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
651 svsk, iov[0].iov_base, iov[0].iov_len, len); 632 svsk, iov[0].iov_base, iov[0].iov_len, len);
652
653 return len; 633 return len;
654} 634}
655 635
@@ -719,8 +699,15 @@ svc_write_space(struct sock *sk)
719 } 699 }
720} 700}
721 701
722static inline void svc_udp_get_dest_address(struct svc_rqst *rqstp, 702/*
723 struct cmsghdr *cmh) 703 * Copy the UDP datagram's destination address to the rqstp structure.
704 * The 'destination' address in this case is the address to which the
705 * peer sent the datagram, i.e. our local address. For multihomed
706 * hosts, this can change from msg to msg. Note that only the IP
707 * address changes, the port number should remain the same.
708 */
709static void svc_udp_get_dest_address(struct svc_rqst *rqstp,
710 struct cmsghdr *cmh)
724{ 711{
725 switch (rqstp->rq_sock->sk_sk->sk_family) { 712 switch (rqstp->rq_sock->sk_sk->sk_family) {
726 case AF_INET: { 713 case AF_INET: {
@@ -787,7 +774,10 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
787 svc_xprt_received(&svsk->sk_xprt); 774 svc_xprt_received(&svsk->sk_xprt);
788 return -EAGAIN; 775 return -EAGAIN;
789 } 776 }
790 rqstp->rq_addrlen = sizeof(rqstp->rq_addr); 777 len = svc_addr_len(svc_addr(rqstp));
778 if (len < 0)
779 return len;
780 rqstp->rq_addrlen = len;
791 if (skb->tstamp.tv64 == 0) { 781 if (skb->tstamp.tv64 == 0) {
792 skb->tstamp = ktime_get_real(); 782 skb->tstamp = ktime_get_real();
793 /* Don't enable netstamp, sunrpc doesn't 783 /* Don't enable netstamp, sunrpc doesn't
@@ -1097,14 +1087,13 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
1097 if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 1087 if (!(newsvsk = svc_setup_socket(serv, newsock, &err,
1098 (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)))) 1088 (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY))))
1099 goto failed; 1089 goto failed;
1100 memcpy(&newsvsk->sk_remote, sin, slen); 1090 svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen);
1101 newsvsk->sk_remotelen = slen;
1102 err = kernel_getsockname(newsock, sin, &slen); 1091 err = kernel_getsockname(newsock, sin, &slen);
1103 if (unlikely(err < 0)) { 1092 if (unlikely(err < 0)) {
1104 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err); 1093 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
1105 slen = offsetof(struct sockaddr, sa_data); 1094 slen = offsetof(struct sockaddr, sa_data);
1106 } 1095 }
1107 memcpy(&newsvsk->sk_local, sin, slen); 1096 svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen);
1108 1097
1109 if (serv->sv_stats) 1098 if (serv->sv_stats)
1110 serv->sv_stats->nettcpconn++; 1099 serv->sv_stats->nettcpconn++;
@@ -1245,6 +1234,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
1245 svsk->sk_reclen = 0; 1234 svsk->sk_reclen = 0;
1246 svsk->sk_tcplen = 0; 1235 svsk->sk_tcplen = 0;
1247 1236
1237 svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt);
1248 svc_xprt_received(&svsk->sk_xprt); 1238 svc_xprt_received(&svsk->sk_xprt);
1249 if (serv->sv_stats) 1239 if (serv->sv_stats)
1250 serv->sv_stats->nettcpcnt++; 1240 serv->sv_stats->nettcpcnt++;
@@ -1805,6 +1795,11 @@ int svc_addsock(struct svc_serv *serv,
1805 else { 1795 else {
1806 svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS); 1796 svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS);
1807 if (svsk) { 1797 if (svsk) {
1798 struct sockaddr_storage addr;
1799 struct sockaddr *sin = (struct sockaddr *)&addr;
1800 int salen;
1801 if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0)
1802 svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
1808 svc_xprt_received(&svsk->sk_xprt); 1803 svc_xprt_received(&svsk->sk_xprt);
1809 err = 0; 1804 err = 0;
1810 } 1805 }
@@ -1831,6 +1826,9 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
1831 int error; 1826 int error;
1832 int type; 1827 int type;
1833 char buf[RPC_MAX_ADDRBUFLEN]; 1828 char buf[RPC_MAX_ADDRBUFLEN];
1829 struct sockaddr_storage addr;
1830 struct sockaddr *newsin = (struct sockaddr *)&addr;
1831 int newlen;
1834 1832
1835 dprintk("svc: svc_create_socket(%s, %d, %s)\n", 1833 dprintk("svc: svc_create_socket(%s, %d, %s)\n",
1836 serv->sv_program->pg_name, protocol, 1834 serv->sv_program->pg_name, protocol,
@@ -1855,12 +1853,18 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
1855 if (error < 0) 1853 if (error < 0)
1856 goto bummer; 1854 goto bummer;
1857 1855
1856 newlen = len;
1857 error = kernel_getsockname(sock, newsin, &newlen);
1858 if (error < 0)
1859 goto bummer;
1860
1858 if (protocol == IPPROTO_TCP) { 1861 if (protocol == IPPROTO_TCP) {
1859 if ((error = kernel_listen(sock, 64)) < 0) 1862 if ((error = kernel_listen(sock, 64)) < 0)
1860 goto bummer; 1863 goto bummer;
1861 } 1864 }
1862 1865
1863 if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { 1866 if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) {
1867 svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen);
1864 svc_xprt_received(&svsk->sk_xprt); 1868 svc_xprt_received(&svsk->sk_xprt);
1865 return (struct svc_xprt *)svsk; 1869 return (struct svc_xprt *)svsk;
1866 } 1870 }