aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
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 /include/linux
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 'include/linux')
-rw-r--r--include/linux/sunrpc/svc_xprt.h51
-rw-r--r--include/linux/sunrpc/svcsock.h4
2 files changed, 51 insertions, 4 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/*