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: Jeff Layton <jlayton@redhat.com> Acked-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
committed by
J. Bruce Fields
parent
363168b4ea
commit
aa9a4ec770
@@ -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)
|
|||||||
};
|
};
|
||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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 {
|
|||||||
/* 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 */
|
||||||
|
Reference in New Issue
Block a user