Date: Sun, 03 May 2026 23:27:37 +0000 From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 457c621add0a - main - nfsd: Disable use of callbacks for NFSv4.0 Message-ID: <69f7d9e9.2677a.243bc206@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=457c621add0a531273ee27798c924c6aaeacc4c1 commit 457c621add0a531273ee27798c924c6aaeacc4c1 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2026-05-03 23:25:45 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2026-05-03 23:25:45 +0000 nfsd: Disable use of callbacks for NFSv4.0 Commit 71ac1ec5c9d9 disabled callbacks for the NFS client for NFSv4.0. This patch does the same for the NFSv4.0 server. The only use for callbacks for NFSv4.0 is delegations and delegations rarely work well for NFSv4.0 anyhow. Therefore, this patch disables callbacks for the NFSv4.0 server. This is the same behavior as occurs when vfs.nfsd.issue_delegations is 0. This change allowed the functions called nfsrv_getclientipaddr() and nfsrv_getipnumber() to be removed from the kernel. MFC after: 2 weeks --- sys/fs/nfsserver/nfs_nfsdstate.c | 269 +++++---------------------------------- 1 file changed, 31 insertions(+), 238 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 4f4aff342872..22e702b001c0 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -165,7 +165,6 @@ static void nfsrv_insertlock(struct nfslock *new_lop, struct nfslock *insert_lop, struct nfsstate *stp, struct nfslockfile *lfp); static void nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp, struct nfslock **other_lopp, struct nfslockfile *lfp); -static int nfsrv_getipnumber(u_char *cp); static int nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags, nfsv4stateid_t *stateidp, int specialid); static int nfsrv_checkgrace(struct nfsrv_descript *nd, struct nfsclient *clp, @@ -4079,279 +4078,73 @@ out: } /* - * Get the client ip address for callbacks. If the strings can't be parsed, - * just set lc_program to 0 to indicate no callbacks are possible. - * (For cases where the address can't be parsed or is 0.0.0.0.0.0, set - * the address to the client's transport address. This won't be used - * for callbacks, but can be printed out by nfsstats for info.) + * Just set lc_program to 0 to indicate no callbacks are possible. + * Set the address to the client's transport address. This won't be used + * for callbacks, but can be printed out by nfsstats for info. * Return error if the xdr can't be parsed, 0 otherwise. */ int nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) { - u_int32_t *tl; - u_char *cp, *cp2; - int i, j, maxalen = 0, minalen = 0; - sa_family_t af; + uint32_t *tl; + int error = 0, i; #ifdef INET - struct sockaddr_in *rin = NULL, *sin; + struct sockaddr_in *rin, *sin; #endif #ifdef INET6 - struct sockaddr_in6 *rin6 = NULL, *sin6; -#endif - u_char *addr; - int error = 0, cantparse = 0; -#ifdef INET - union { - in_addr_t ival; - u_char cval[4]; - } ip; -#endif -#if defined(INET6) || defined(INET) - union { - in_port_t sval; - u_char cval[2]; - } port; + struct sockaddr_in6 *rin6, *sin6; #endif - /* 8 is the maximum length of the port# string. */ - addr = malloc(INET6_ADDRSTRLEN + 8, M_TEMP, M_WAITOK); clp->lc_req.nr_client = NULL; clp->lc_req.nr_lock = 0; - af = AF_UNSPEC; - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); i = fxdr_unsigned(int, *tl); - if (i >= 3 && i <= 4) { - error = nfsrv_mtostr(nd, addr, i); + if (i < 0) { + error = NFSERR_BADXDR; + goto nfsmout; + } else if (i > 0) { + error = nfsm_advance(nd, NFSM_RNDUP(i), -1); if (error) goto nfsmout; -#ifdef INET - if (!strcmp(addr, "tcp")) { - clp->lc_flags |= LCL_TCPCALLBACK; - clp->lc_req.nr_sotype = SOCK_STREAM; - clp->lc_req.nr_soproto = IPPROTO_TCP; - af = AF_INET; - } else if (!strcmp(addr, "udp")) { - clp->lc_req.nr_sotype = SOCK_DGRAM; - clp->lc_req.nr_soproto = IPPROTO_UDP; - af = AF_INET; - } -#endif -#ifdef INET6 - if (af == AF_UNSPEC) { - if (!strcmp(addr, "tcp6")) { - clp->lc_flags |= LCL_TCPCALLBACK; - clp->lc_req.nr_sotype = SOCK_STREAM; - clp->lc_req.nr_soproto = IPPROTO_TCP; - af = AF_INET6; - } else if (!strcmp(addr, "udp6")) { - clp->lc_req.nr_sotype = SOCK_DGRAM; - clp->lc_req.nr_soproto = IPPROTO_UDP; - af = AF_INET6; - } - } -#endif - if (af == AF_UNSPEC) { - cantparse = 1; - } - } else { - cantparse = 1; - if (i > 0) { - error = nfsm_advance(nd, NFSM_RNDUP(i), -1); - if (error) - goto nfsmout; - } } - /* - * The caller has allocated clp->lc_req.nr_nam to be large enough - * for either AF_INET or AF_INET6 and zeroed out the contents. - * maxalen is set to the maximum length of the host IP address string - * plus 8 for the maximum length of the port#. - * minalen is set to the minimum length of the host IP address string - * plus 4 for the minimum length of the port#. - * These lengths do not include NULL termination, - * so INET[6]_ADDRSTRLEN - 1 is used in the calculations. - */ - switch (af) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + i = fxdr_unsigned(int, *tl); + if (i < 0) { + error = NFSERR_BADXDR; + goto nfsmout; + } else if (i > 0) { + error = nfsm_advance(nd, NFSM_RNDUP(i), -1); + if (error) + goto nfsmout; + } + switch (nd->nd_nam->sa_family) { #ifdef INET case AF_INET: + sin = (struct sockaddr_in *)nd->nd_nam; rin = (struct sockaddr_in *)clp->lc_req.nr_nam; rin->sin_family = AF_INET; rin->sin_len = sizeof(struct sockaddr_in); - maxalen = INET_ADDRSTRLEN - 1 + 8; - minalen = 7 + 4; + rin->sin_addr.s_addr = sin->sin_addr.s_addr; + rin->sin_port = 0x0; break; #endif #ifdef INET6 case AF_INET6: + sin6 = (struct sockaddr_in6 *)nd->nd_nam; rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; rin6->sin6_family = AF_INET6; rin6->sin6_len = sizeof(struct sockaddr_in6); - maxalen = INET6_ADDRSTRLEN - 1 + 8; - minalen = 3 + 4; + rin6->sin6_addr = sin6->sin6_addr; + rin6->sin6_port = 0x0; break; #endif } - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - i = fxdr_unsigned(int, *tl); - if (i < 0) { - error = NFSERR_BADXDR; - goto nfsmout; - } else if (i == 0) { - cantparse = 1; - } else if (!cantparse && i <= maxalen && i >= minalen) { - error = nfsrv_mtostr(nd, addr, i); - if (error) - goto nfsmout; - - /* - * Parse out the address fields. We expect 6 decimal numbers - * separated by '.'s for AF_INET and two decimal numbers - * preceded by '.'s for AF_INET6. - */ - cp = NULL; - switch (af) { -#ifdef INET6 - /* - * For AF_INET6, first parse the host address. - */ - case AF_INET6: - cp = strchr(addr, '.'); - if (cp != NULL) { - *cp++ = '\0'; - if (inet_pton(af, addr, &rin6->sin6_addr) == 1) - i = 4; - else { - cp = NULL; - cantparse = 1; - } - } - break; -#endif -#ifdef INET - case AF_INET: - cp = addr; - i = 0; - break; -#endif - } - while (cp != NULL && *cp && i < 6) { - cp2 = cp; - while (*cp2 && *cp2 != '.') - cp2++; - if (*cp2) - *cp2++ = '\0'; - else if (i != 5) { - cantparse = 1; - break; - } - j = nfsrv_getipnumber(cp); - if (j >= 0) { - if (i < 4) -#ifdef INET - ip.cval[3 - i] = j; -#else - ; -#endif -#if defined(INET6) || defined(INET) - else - port.cval[5 - i] = j; -#endif - } else { - cantparse = 1; - break; - } - cp = cp2; - i++; - } - if (!cantparse) { - /* - * The host address INADDR_ANY is (mis)used to indicate - * "there is no valid callback address". - */ - switch (af) { -#ifdef INET6 - case AF_INET6: - if (!IN6_ARE_ADDR_EQUAL(&rin6->sin6_addr, - &in6addr_any)) - rin6->sin6_port = htons(port.sval); - else - cantparse = 1; - break; -#endif -#ifdef INET - case AF_INET: - if (ip.ival != INADDR_ANY) { - rin->sin_addr.s_addr = htonl(ip.ival); - rin->sin_port = htons(port.sval); - } else { - cantparse = 1; - } - break; -#endif - } - } - } else { - cantparse = 1; - if (i > 0) { - error = nfsm_advance(nd, NFSM_RNDUP(i), -1); - if (error) - goto nfsmout; - } - } - if (cantparse) { - switch (nd->nd_nam->sa_family) { -#ifdef INET - case AF_INET: - sin = (struct sockaddr_in *)nd->nd_nam; - rin = (struct sockaddr_in *)clp->lc_req.nr_nam; - rin->sin_family = AF_INET; - rin->sin_len = sizeof(struct sockaddr_in); - rin->sin_addr.s_addr = sin->sin_addr.s_addr; - rin->sin_port = 0x0; - break; -#endif -#ifdef INET6 - case AF_INET6: - sin6 = (struct sockaddr_in6 *)nd->nd_nam; - rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; - rin6->sin6_family = AF_INET6; - rin6->sin6_len = sizeof(struct sockaddr_in6); - rin6->sin6_addr = sin6->sin6_addr; - rin6->sin6_port = 0x0; - break; -#endif - } - clp->lc_program = 0; - } + clp->lc_program = 0; nfsmout: - free(addr, M_TEMP); NFSEXITCODE2(error, nd); return (error); } -/* - * Turn a string of up to three decimal digits into a number. Return -1 upon - * error. - */ -static int -nfsrv_getipnumber(u_char *cp) -{ - int i = 0, j = 0; - - while (*cp) { - if (j > 2 || *cp < '0' || *cp > '9') - return (-1); - i *= 10; - i += (*cp - '0'); - cp++; - j++; - } - if (i < 256) - return (i); - return (-1); -} - /* * This function checks for restart conditions. */home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f7d9e9.2677a.243bc206>
