diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-08-14 12:57:57 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-08-21 11:27:43 -0400 |
commit | aa9a4ec7707a5391cde556f3fa1b0eb4bca3bcf6 (patch) | |
tree | abb684bea62a77a0172d6be2f45f0414acedc5cc | |
parent | 363168b4ea8ec26aeb982ac6024a09f907ecd27e (diff) |
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>
-rw-r--r-- | fs/nfsd/nfs4callback.c | 11 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 81 | ||||
-rw-r--r-- | include/linux/nfsd/state.h | 4 |
3 files changed, 13 insertions, 83 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 3fd23f7aceca..81d1c5285dcc 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -377,7 +377,6 @@ static int max_cb_time(void) | |||
377 | 377 | ||
378 | int setup_callback_client(struct nfs4_client *clp) | 378 | int setup_callback_client(struct nfs4_client *clp) |
379 | { | 379 | { |
380 | struct sockaddr_in addr; | ||
381 | struct nfs4_cb_conn *cb = &clp->cl_cb_conn; | 380 | struct nfs4_cb_conn *cb = &clp->cl_cb_conn; |
382 | struct rpc_timeout timeparms = { | 381 | struct rpc_timeout timeparms = { |
383 | .to_initval = max_cb_time(), | 382 | .to_initval = max_cb_time(), |
@@ -385,8 +384,8 @@ int setup_callback_client(struct nfs4_client *clp) | |||
385 | }; | 384 | }; |
386 | struct rpc_create_args args = { | 385 | struct rpc_create_args args = { |
387 | .protocol = IPPROTO_TCP, | 386 | .protocol = IPPROTO_TCP, |
388 | .address = (struct sockaddr *)&addr, | 387 | .address = (struct sockaddr *) &cb->cb_addr, |
389 | .addrsize = sizeof(addr), | 388 | .addrsize = cb->cb_addrlen, |
390 | .timeout = &timeparms, | 389 | .timeout = &timeparms, |
391 | .program = &cb_program, | 390 | .program = &cb_program, |
392 | .prognumber = cb->cb_prog, | 391 | .prognumber = cb->cb_prog, |
@@ -400,12 +399,6 @@ int setup_callback_client(struct nfs4_client *clp) | |||
400 | if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) | 399 | if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) |
401 | return -EINVAL; | 400 | return -EINVAL; |
402 | 401 | ||
403 | /* Initialize address */ | ||
404 | memset(&addr, 0, sizeof(addr)); | ||
405 | addr.sin_family = AF_INET; | ||
406 | addr.sin_port = htons(cb->cb_port); | ||
407 | addr.sin_addr.s_addr = htonl(cb->cb_addr); | ||
408 | |||
409 | /* Create RPC client */ | 402 | /* Create RPC client */ |
410 | client = rpc_create(&args); | 403 | client = rpc_create(&args); |
411 | if (IS_ERR(client)) { | 404 | if (IS_ERR(client)) { |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bfc14d879ea1..96a742308cee 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -897,76 +897,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, | |||
897 | return NULL; | 897 | return NULL; |
898 | } | 898 | } |
899 | 899 | ||
900 | /* a helper function for parse_callback */ | ||
901 | static int | ||
902 | parse_octet(unsigned int *lenp, char **addrp) | ||
903 | { | ||
904 | unsigned int len = *lenp; | ||
905 | char *p = *addrp; | ||
906 | int n = -1; | ||
907 | char c; | ||
908 | |||
909 | for (;;) { | ||
910 | if (!len) | ||
911 | break; | ||
912 | len--; | ||
913 | c = *p++; | ||
914 | if (c == '.') | ||
915 | break; | ||
916 | if ((c < '0') || (c > '9')) { | ||
917 | n = -1; | ||
918 | break; | ||
919 | } | ||
920 | if (n < 0) | ||
921 | n = 0; | ||
922 | n = (n * 10) + (c - '0'); | ||
923 | if (n > 255) { | ||
924 | n = -1; | ||
925 | break; | ||
926 | } | ||
927 | } | ||
928 | *lenp = len; | ||
929 | *addrp = p; | ||
930 | return n; | ||
931 | } | ||
932 | |||
933 | /* parse and set the setclientid ipv4 callback address */ | ||
934 | static int | ||
935 | parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp) | ||
936 | { | ||
937 | int temp = 0; | ||
938 | u32 cbaddr = 0; | ||
939 | u16 cbport = 0; | ||
940 | u32 addrlen = addr_len; | ||
941 | char *addr = addr_val; | ||
942 | int i, shift; | ||
943 | |||
944 | /* ipaddress */ | ||
945 | shift = 24; | ||
946 | for(i = 4; i > 0 ; i--) { | ||
947 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
948 | return 0; | ||
949 | } | ||
950 | cbaddr |= (temp << shift); | ||
951 | if (shift > 0) | ||
952 | shift -= 8; | ||
953 | } | ||
954 | *cbaddrp = cbaddr; | ||
955 | |||
956 | /* port */ | ||
957 | shift = 8; | ||
958 | for(i = 2; i > 0 ; i--) { | ||
959 | if ((temp = parse_octet(&addrlen, &addr)) < 0) { | ||
960 | return 0; | ||
961 | } | ||
962 | cbport |= (temp << shift); | ||
963 | if (shift > 0) | ||
964 | shift -= 8; | ||
965 | } | ||
966 | *cbportp = cbport; | ||
967 | return 1; | ||
968 | } | ||
969 | |||
970 | static void | 900 | static void |
971 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | 901 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) |
972 | { | 902 | { |
@@ -976,14 +906,21 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) | |||
976 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) | 906 | if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3)) |
977 | goto out_err; | 907 | goto out_err; |
978 | 908 | ||
979 | if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val, | 909 | cb->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val, |
980 | &cb->cb_addr, &cb->cb_port))) | 910 | se->se_callback_addr_len, |
911 | (struct sockaddr *) &cb->cb_addr, | ||
912 | sizeof(cb->cb_addr)); | ||
913 | |||
914 | if (!cb->cb_addrlen || cb->cb_addr.ss_family != AF_INET) | ||
981 | goto out_err; | 915 | goto out_err; |
916 | |||
982 | cb->cb_minorversion = 0; | 917 | cb->cb_minorversion = 0; |
983 | cb->cb_prog = se->se_callback_prog; | 918 | cb->cb_prog = se->se_callback_prog; |
984 | cb->cb_ident = se->se_callback_ident; | 919 | cb->cb_ident = se->se_callback_ident; |
985 | return; | 920 | return; |
986 | out_err: | 921 | out_err: |
922 | cb->cb_addr.ss_family = AF_UNSPEC; | ||
923 | cb->cb_addrlen = 0; | ||
987 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " | 924 | dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " |
988 | "will not receive delegations\n", | 925 | "will not receive delegations\n", |
989 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); | 926 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); |
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index 3510ddd4be49..fb0c404c7c5c 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h | |||
@@ -81,8 +81,8 @@ struct nfs4_delegation { | |||
81 | /* client delegation callback info */ | 81 | /* client delegation callback info */ |
82 | struct nfs4_cb_conn { | 82 | struct nfs4_cb_conn { |
83 | /* SETCLIENTID info */ | 83 | /* SETCLIENTID info */ |
84 | u32 cb_addr; | 84 | struct sockaddr_storage cb_addr; |
85 | unsigned short cb_port; | 85 | size_t cb_addrlen; |
86 | u32 cb_prog; | 86 | u32 cb_prog; |
87 | u32 cb_minorversion; | 87 | u32 cb_minorversion; |
88 | u32 cb_ident; /* minorversion 0 only */ | 88 | u32 cb_ident; /* minorversion 0 only */ |