Commit aa9a4ec7 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

nfsd: convert nfs4_cb_conn struct to hold address in sockaddr_storage

...rather than as a separate address and port fields. This will be
necessary for implementing callbacks over IPv6. Also, convert
gen_callback to use the standard rpcuaddr2sockaddr routine rather than
its own private one.
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Acked-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 363168b4
...@@ -377,7 +377,6 @@ static int max_cb_time(void) ...@@ -377,7 +377,6 @@ static int max_cb_time(void)
int setup_callback_client(struct nfs4_client *clp) int setup_callback_client(struct nfs4_client *clp)
{ {
struct sockaddr_in addr;
struct nfs4_cb_conn *cb = &clp->cl_cb_conn; struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
struct rpc_timeout timeparms = { struct rpc_timeout timeparms = {
.to_initval = max_cb_time(), .to_initval = max_cb_time(),
...@@ -385,8 +384,8 @@ int setup_callback_client(struct nfs4_client *clp) ...@@ -385,8 +384,8 @@ int setup_callback_client(struct nfs4_client *clp)
}; };
struct rpc_create_args args = { struct rpc_create_args args = {
.protocol = IPPROTO_TCP, .protocol = IPPROTO_TCP,
.address = (struct sockaddr *)&addr, .address = (struct sockaddr *) &cb->cb_addr,
.addrsize = sizeof(addr), .addrsize = cb->cb_addrlen,
.timeout = &timeparms, .timeout = &timeparms,
.program = &cb_program, .program = &cb_program,
.prognumber = cb->cb_prog, .prognumber = cb->cb_prog,
...@@ -400,12 +399,6 @@ int setup_callback_client(struct nfs4_client *clp) ...@@ -400,12 +399,6 @@ int setup_callback_client(struct nfs4_client *clp)
if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
return -EINVAL; return -EINVAL;
/* Initialize address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(cb->cb_port);
addr.sin_addr.s_addr = htonl(cb->cb_addr);
/* Create RPC client */ /* Create RPC client */
client = rpc_create(&args); client = rpc_create(&args);
if (IS_ERR(client)) { if (IS_ERR(client)) {
......
...@@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, ...@@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval,
return NULL; return NULL;
} }
/* a helper function for parse_callback */
static int
parse_octet(unsigned int *lenp, char **addrp)
{
unsigned int len = *lenp;
char *p = *addrp;
int n = -1;
char c;
for (;;) {
if (!len)
break;
len--;
c = *p++;
if (c == '.')
break;
if ((c < '0') || (c > '9')) {
n = -1;
break;
}
if (n < 0)
n = 0;
n = (n * 10) + (c - '0');
if (n > 255) {
n = -1;
break;
}
}
*lenp = len;
*addrp = p;
return n;
}
/* parse and set the setclientid ipv4 callback address */
static int
parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
{
int temp = 0;
u32 cbaddr = 0;
u16 cbport = 0;
u32 addrlen = addr_len;
char *addr = addr_val;
int i, shift;
/* ipaddress */
shift = 24;
for(i = 4; i > 0 ; i--) {
if ((temp = parse_octet(&addrlen, &addr)) < 0) {
return 0;
}
cbaddr |= (temp << shift);
if (shift > 0)
shift -= 8;
}
*cbaddrp = cbaddr;
/* port */
shift = 8;
for(i = 2; i > 0 ; i--) {
if ((temp = parse_octet(&addrlen, &addr)) < 0) {
return 0;
}
cbport |= (temp << shift);
if (shift > 0)
shift -= 8;
}
*cbportp = cbport;
return 1;
}
static void static void
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
{ {
...@@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) ...@@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
goto out_err; goto out_err;
if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val, cb->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val,
&cb->cb_addr, &cb->cb_port))) se->se_callback_addr_len,
(struct sockaddr *) &cb->cb_addr,
sizeof(cb->cb_addr));
if (!cb->cb_addrlen || cb->cb_addr.ss_family != AF_INET)
goto out_err; goto out_err;
cb->cb_minorversion = 0; cb->cb_minorversion = 0;
cb->cb_prog = se->se_callback_prog; cb->cb_prog = se->se_callback_prog;
cb->cb_ident = se->se_callback_ident; cb->cb_ident = se->se_callback_ident;
return; return;
out_err: out_err:
cb->cb_addr.ss_family = AF_UNSPEC;
cb->cb_addrlen = 0;
dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
"will not receive delegations\n", "will not receive delegations\n",
clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
......
...@@ -81,8 +81,8 @@ struct nfs4_delegation { ...@@ -81,8 +81,8 @@ struct nfs4_delegation {
/* client delegation callback info */ /* client delegation callback info */
struct nfs4_cb_conn { struct nfs4_cb_conn {
/* SETCLIENTID info */ /* SETCLIENTID info */
u32 cb_addr; struct sockaddr_storage cb_addr;
unsigned short cb_port; size_t cb_addrlen;
u32 cb_prog; u32 cb_prog;
u32 cb_minorversion; u32 cb_minorversion;
u32 cb_ident; /* minorversion 0 only */ u32 cb_ident; /* minorversion 0 only */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment