From owner-svn-src-head@freebsd.org Fri Jul 27 23:10:29 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 62C7F1059E0D; Fri, 27 Jul 2018 23:10:29 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0F1648E237; Fri, 27 Jul 2018 23:10:29 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E18DB1E47B; Fri, 27 Jul 2018 23:10:28 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6RNASuM060575; Fri, 27 Jul 2018 23:10:28 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6RNASXs060574; Fri, 27 Jul 2018 23:10:28 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201807272310.w6RNASXs060574@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 27 Jul 2018 23:10:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336795 - head/usr.sbin/nfsd X-SVN-Group: head X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: head/usr.sbin/nfsd X-SVN-Commit-Revision: 336795 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Jul 2018 23:10:29 -0000 Author: rmacklem Date: Fri Jul 27 23:10:28 2018 New Revision: 336795 URL: https://svnweb.freebsd.org/changeset/base/336795 Log: Add support for IPv6 addresses to the pNFS "-p" option. This patch adds code to handle IPv6 addresses returned by getaddrinfo() for the host entries in the "-p" command line argument. If the IPv6 address is a link local address, only use it if it is the only address for the host. This is done since there is no way to know if the NFSv4.1 pNFS client is in the same scope zone as the MDS. inet_ntop() is used for the IPv6 address translation, since the client will have no use for the scope zone suffix and inet_ntop() does not put this in the address string. Discussed with: bu7cher@yandex.ru Modified: head/usr.sbin/nfsd/nfsd.c Modified: head/usr.sbin/nfsd/nfsd.c ============================================================================== --- head/usr.sbin/nfsd/nfsd.c Fri Jul 27 22:46:42 2018 (r336794) +++ head/usr.sbin/nfsd/nfsd.c Fri Jul 27 23:10:28 2018 (r336795) @@ -1179,14 +1179,16 @@ backup_stable(__unused int signo) static void parse_dsserver(const char *optionarg, struct nfsd_nfsd_args *nfsdargp) { - char *ad, *cp, *cp2, *dsaddr, *dshost, *dspath, *dsvol, nfsprt[9]; - char *mdspath, *mdsp; + char *cp, *cp2, *dsaddr, *dshost, *dspath, *dsvol, nfsprt[9]; + char *mdspath, *mdsp, ip6[INET6_ADDRSTRLEN]; + const char *ad; int ecode; u_int adsiz, dsaddrcnt, dshostcnt, dspathcnt, hostsiz, pathsiz; u_int mdspathcnt; size_t dsaddrsiz, dshostsiz, dspathsiz, nfsprtsiz, mdspathsiz; - struct addrinfo hints, *ai_tcp; + struct addrinfo hints, *ai_tcp, *res; struct sockaddr_in sin; + struct sockaddr_in6 sin6; cp = strdup(optionarg); if (cp == NULL) @@ -1275,22 +1277,55 @@ parse_dsserver(const char *optionarg, struct nfsd_nfsd /* Get the fully qualified domain name and IP address. */ memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = AF_INET; + hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; + hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; ecode = getaddrinfo(cp, NULL, &hints, &ai_tcp); if (ecode != 0) err(1, "getaddrinfo pnfs: %s %s", cp, gai_strerror(ecode)); - if (ai_tcp->ai_addr->sa_family != AF_INET || - ai_tcp->ai_addrlen < sizeof(sin)) - err(1, "getaddrinfo() returned non-INET address"); - /* Mips cares about sockaddr_in alignment, so copy the addr. */ - memcpy(&sin, ai_tcp->ai_addr, sizeof(sin)); + ad = NULL; + for (res = ai_tcp; res != NULL; res = res->ai_next) { + if (res->ai_addr->sa_family == AF_INET) { + if (res->ai_addrlen < sizeof(sin)) + err(1, "getaddrinfo() returned " + "undersized IPv4 address"); + /* + * Mips cares about sockaddr_in alignment, + * so copy the address. + */ + memcpy(&sin, res->ai_addr, sizeof(sin)); + ad = inet_ntoa(sin.sin_addr); + break; + } else if (res->ai_family == AF_INET6) { + if (res->ai_addrlen < sizeof(sin6)) + err(1, "getaddrinfo() returned " + "undersized IPv6 address"); + /* + * Mips cares about sockaddr_in6 alignment, + * so copy the address. + */ + memcpy(&sin6, res->ai_addr, sizeof(sin6)); + ad = inet_ntop(AF_INET6, &sin6.sin6_addr, ip6, + sizeof(ip6)); + /* + * XXX + * Since a link local address will only + * work if the client and DS are in the + * same scope zone, only use it if it is + * the only address. + */ + if (ad != NULL && + !IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) + break; + } + } + if (ad == NULL) + err(1, "No IP address for %s", cp); + /* Append this address to dsaddr. */ - ad = inet_ntoa(sin.sin_addr); adsiz = strlen(ad); if (dsaddrcnt + adsiz + nfsprtsiz + 1 > dsaddrsiz) { dsaddrsiz *= 2;