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:
		
					parent
					
						
							
								363168b4ea
							
						
					
				
			
			
				commit
				
					
						aa9a4ec770
					
				
			
		
					 3 changed files with 13 additions and 83 deletions
				
			
		|  | @ -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 */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeff Layton
				Jeff Layton