diff options
author | Chuck Lever <cel@netapp.com> | 2006-01-03 03:55:51 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:56 -0500 |
commit | 922004120b10dcb0ce04b55014168e8a7a8c1a0e (patch) | |
tree | 4209bbd1043d9ddf09f2f277a65af758aa3631da /net | |
parent | 35f5a422ce1af836007f811b613c440d0e348e06 (diff) |
SUNRPC: transport switch API for setting port number
At some point, transport endpoint addresses will no longer be IPv4. To hide
the structure of the rpc_xprt's address field from ULPs and port mappers,
add an API for setting the port number during an RPC bind operation.
Test-plan:
Destructive testing (unplugging the network temporarily). Connectathon
with UDP and TCP. NFSv2/3 and NFSv4 mounting should be carefully checked.
Probably need to rig a server where certain services aren't running, or
that returns an error for some typical operation.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/pmap_clnt.c | 8 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 14 |
2 files changed, 19 insertions, 3 deletions
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index cad4568fbbe2..0935adb91b3c 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c | |||
@@ -131,10 +131,13 @@ static void | |||
131 | pmap_getport_done(struct rpc_task *task) | 131 | pmap_getport_done(struct rpc_task *task) |
132 | { | 132 | { |
133 | struct rpc_clnt *clnt = task->tk_client; | 133 | struct rpc_clnt *clnt = task->tk_client; |
134 | struct rpc_xprt *xprt = task->tk_xprt; | ||
134 | struct rpc_portmap *map = clnt->cl_pmap; | 135 | struct rpc_portmap *map = clnt->cl_pmap; |
135 | 136 | ||
136 | dprintk("RPC: %4d pmap_getport_done(status %d, port %d)\n", | 137 | dprintk("RPC: %4d pmap_getport_done(status %d, port %d)\n", |
137 | task->tk_pid, task->tk_status, clnt->cl_port); | 138 | task->tk_pid, task->tk_status, clnt->cl_port); |
139 | |||
140 | xprt->ops->set_port(xprt, 0); | ||
138 | if (task->tk_status < 0) { | 141 | if (task->tk_status < 0) { |
139 | /* Make the calling task exit with an error */ | 142 | /* Make the calling task exit with an error */ |
140 | task->tk_action = rpc_exit_task; | 143 | task->tk_action = rpc_exit_task; |
@@ -142,9 +145,8 @@ pmap_getport_done(struct rpc_task *task) | |||
142 | /* Program not registered */ | 145 | /* Program not registered */ |
143 | rpc_exit(task, -EACCES); | 146 | rpc_exit(task, -EACCES); |
144 | } else { | 147 | } else { |
145 | /* byte-swap port number first */ | 148 | xprt->ops->set_port(xprt, clnt->cl_port); |
146 | clnt->cl_port = htons(clnt->cl_port); | 149 | clnt->cl_port = htons(clnt->cl_port); |
147 | clnt->cl_xprt->addr.sin_port = clnt->cl_port; | ||
148 | } | 150 | } |
149 | spin_lock(&pmap_lock); | 151 | spin_lock(&pmap_lock); |
150 | map->pm_binding = 0; | 152 | map->pm_binding = 0; |
@@ -205,7 +207,7 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileg | |||
205 | xprt = xprt_create_proto(proto, srvaddr, NULL); | 207 | xprt = xprt_create_proto(proto, srvaddr, NULL); |
206 | if (IS_ERR(xprt)) | 208 | if (IS_ERR(xprt)) |
207 | return (struct rpc_clnt *)xprt; | 209 | return (struct rpc_clnt *)xprt; |
208 | xprt->addr.sin_port = htons(RPC_PMAP_PORT); | 210 | xprt->ops->set_port(xprt, RPC_PMAP_PORT); |
209 | if (!privileged) | 211 | if (!privileged) |
210 | xprt->resvport = 0; | 212 | xprt->resvport = 0; |
211 | 213 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 51f07c9a751b..3e8893001479 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -921,6 +921,18 @@ static void xs_udp_timer(struct rpc_task *task) | |||
921 | xprt_adjust_cwnd(task, -ETIMEDOUT); | 921 | xprt_adjust_cwnd(task, -ETIMEDOUT); |
922 | } | 922 | } |
923 | 923 | ||
924 | /** | ||
925 | * xs_set_port - reset the port number in the remote endpoint address | ||
926 | * @xprt: generic transport | ||
927 | * @port: new port number | ||
928 | * | ||
929 | */ | ||
930 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | ||
931 | { | ||
932 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); | ||
933 | xprt->addr.sin_port = htons(port); | ||
934 | } | ||
935 | |||
924 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 936 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) |
925 | { | 937 | { |
926 | struct sockaddr_in myaddr = { | 938 | struct sockaddr_in myaddr = { |
@@ -1161,6 +1173,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1161 | .set_buffer_size = xs_udp_set_buffer_size, | 1173 | .set_buffer_size = xs_udp_set_buffer_size, |
1162 | .reserve_xprt = xprt_reserve_xprt_cong, | 1174 | .reserve_xprt = xprt_reserve_xprt_cong, |
1163 | .release_xprt = xprt_release_xprt_cong, | 1175 | .release_xprt = xprt_release_xprt_cong, |
1176 | .set_port = xs_set_port, | ||
1164 | .connect = xs_connect, | 1177 | .connect = xs_connect, |
1165 | .buf_alloc = rpc_malloc, | 1178 | .buf_alloc = rpc_malloc, |
1166 | .buf_free = rpc_free, | 1179 | .buf_free = rpc_free, |
@@ -1175,6 +1188,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1175 | static struct rpc_xprt_ops xs_tcp_ops = { | 1188 | static struct rpc_xprt_ops xs_tcp_ops = { |
1176 | .reserve_xprt = xprt_reserve_xprt, | 1189 | .reserve_xprt = xprt_reserve_xprt, |
1177 | .release_xprt = xprt_release_xprt, | 1190 | .release_xprt = xprt_release_xprt, |
1191 | .set_port = xs_set_port, | ||
1178 | .connect = xs_connect, | 1192 | .connect = xs_connect, |
1179 | .buf_alloc = rpc_malloc, | 1193 | .buf_alloc = rpc_malloc, |
1180 | .buf_free = rpc_free, | 1194 | .buf_free = rpc_free, |