aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4callback.c1
-rw-r--r--fs/nfsd/nfs4state.c22
-rw-r--r--fs/nfsd/state.h1
3 files changed, 21 insertions, 3 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index a08580553fda..dd183af24fe6 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -484,6 +484,7 @@ static int setup_callback_client(struct nfs4_client *clp,
484 .net = &init_net, 484 .net = &init_net,
485 .address = (struct sockaddr *) &conn->cb_addr, 485 .address = (struct sockaddr *) &conn->cb_addr,
486 .addrsize = conn->cb_addrlen, 486 .addrsize = conn->cb_addrlen,
487 .saddress = (struct sockaddr *) &conn->cb_saddr,
487 .timeout = &timeparms, 488 .timeout = &timeparms,
488 .program = &cb_program, 489 .program = &cb_program,
489 .version = 0, 490 .version = 0,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 87d4c48b6069..b583e4e800ab 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1163,10 +1163,26 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
1163 return NULL; 1163 return NULL;
1164} 1164}
1165 1165
1166static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr)
1167{
1168 switch (family) {
1169 case AF_INET:
1170 ((struct sockaddr_in *)sa)->sin_family = AF_INET;
1171 ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr;
1172 return;
1173 case AF_INET6:
1174 ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6;
1175 ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6;
1176 return;
1177 }
1178}
1179
1166static void 1180static void
1167gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid) 1181gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
1168{ 1182{
1169 struct nfs4_cb_conn *conn = &clp->cl_cb_conn; 1183 struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1184 struct sockaddr *sa = svc_addr(rqstp);
1185 u32 scopeid = rpc_get_scope_id(sa);
1170 unsigned short expected_family; 1186 unsigned short expected_family;
1171 1187
1172 /* Currently, we only support tcp and tcp6 for the callback channel */ 1188 /* Currently, we only support tcp and tcp6 for the callback channel */
@@ -1192,6 +1208,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid)
1192 1208
1193 conn->cb_prog = se->se_callback_prog; 1209 conn->cb_prog = se->se_callback_prog;
1194 conn->cb_ident = se->se_callback_ident; 1210 conn->cb_ident = se->se_callback_ident;
1211 rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr);
1195 return; 1212 return;
1196out_err: 1213out_err:
1197 conn->cb_addr.ss_family = AF_UNSPEC; 1214 conn->cb_addr.ss_family = AF_UNSPEC;
@@ -1768,7 +1785,6 @@ __be32
1768nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1785nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1769 struct nfsd4_setclientid *setclid) 1786 struct nfsd4_setclientid *setclid)
1770{ 1787{
1771 struct sockaddr *sa = svc_addr(rqstp);
1772 struct xdr_netobj clname = { 1788 struct xdr_netobj clname = {
1773 .len = setclid->se_namelen, 1789 .len = setclid->se_namelen,
1774 .data = setclid->se_name, 1790 .data = setclid->se_name,
@@ -1871,7 +1887,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1871 * for consistent minorversion use throughout: 1887 * for consistent minorversion use throughout:
1872 */ 1888 */
1873 new->cl_minorversion = 0; 1889 new->cl_minorversion = 0;
1874 gen_callback(new, setclid, rpc_get_scope_id(sa)); 1890 gen_callback(new, setclid, rqstp);
1875 add_to_unconfirmed(new, strhashval); 1891 add_to_unconfirmed(new, strhashval);
1876 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; 1892 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
1877 setclid->se_clientid.cl_id = new->cl_clientid.cl_id; 1893 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 84b230217b1b..cf6dc83fd545 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -96,6 +96,7 @@ struct nfs4_delegation {
96struct nfs4_cb_conn { 96struct nfs4_cb_conn {
97 /* SETCLIENTID info */ 97 /* SETCLIENTID info */
98 struct sockaddr_storage cb_addr; 98 struct sockaddr_storage cb_addr;
99 struct sockaddr_storage cb_saddr;
99 size_t cb_addrlen; 100 size_t cb_addrlen;
100 u32 cb_prog; /* used only in 4.0 case; 101 u32 cb_prog; /* used only in 4.0 case;
101 per-session otherwise */ 102 per-session otherwise */