aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
authorTom Tucker <tom@opengridcomputing.com>2007-12-30 22:08:12 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:12 -0500
commit9dbc240f199c16c3c0859c255ad52a663d8ee51d (patch)
tree0e81dd425c36590e65accfe9654d905632783c7f /net/sunrpc/svc_xprt.c
parent8c7b0172a1db8120d25ecb4eff69664c52ee7639 (diff)
svc: Move the sockaddr information to svc_xprt
This patch moves the transport sockaddr to the svc_xprt structure. Convenience functions are added to set and get the local and remote addresses of a transport from the transport provider as well as determine the length of a sockaddr. A transport is responsible for setting the xpt_local and xpt_remote addresses in the svc_xprt structure as part of transport creation and xpo_accept processing. This cannot be done in a generic way and in fact varies between TCP, UDP and RDMA. A set of xpo_ functions (e.g. getlocalname, getremotename) could have been added but this would have resulted in additional caching and copying of the addresses around. Note that the xpt_local address should also be set on listening endpoints; for TCP/RDMA this is done as part of endpoint creation. For connected transports like TCP and RDMA, the addresses never change and can be set once and copied into the rqstp structure for each request. For UDP, however, the local and remote addresses may change for each request. In this case, the address information is obtained from the UDP recvmsg info and copied into the rqstp structure from there. A svc_xprt_local_port function was also added that returns the local port given a transport. This is used by svc_create_xprt when returning the port associated with a newly created transport, and later when creating a generic find transport service to check if a service is already listening on a given port. Signed-off-by: Tom Tucker <tom@opengridcomputing.com> Acked-by: Neil Brown <neilb@suse.de> Reviewed-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Greg Banks <gnb@sgi.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c31
1 files changed, 29 insertions, 2 deletions
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