From 593f0dec5d50d8a970d2cea14879696207c4d7b5 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Mon, 13 Apr 1998 12:11:24 +0000 Subject: [PATCH] Fixes for using amd with non-NFSv3 servers and for choosing the right address for a multihomed server. PR: bin/6231, bin/4678 Submitted by: Mika Nystrom fh_error is meaningless + * since we are already fixing the problem + * We don't want it to get back to the caller! + * Mount is now still "in progress" + * + */ + + fp->fh_error = -1; fp->fh_id = FHID_ALLOC(); fp->fh_mountres.mr_version = MOUNTVERS; call_mountd(fp, MOUNTPROC_MNT, MOUNTVERS, got_nfs_fh, fp->fh_wchan); diff --git a/usr.sbin/amd/amd/srvr_nfs.c b/usr.sbin/amd/amd/srvr_nfs.c index 22e99fca81d..0672c8e637e 100644 --- a/usr.sbin/amd/amd/srvr_nfs.c +++ b/usr.sbin/amd/amd/srvr_nfs.c @@ -37,7 +37,7 @@ * * @(#)srvr_nfs.c 8.1 (Berkeley) 6/6/93 * - * $Id$ + * $Id: srvr_nfs.c,v 1.4 1997/02/22 16:01:44 peter Exp $ * */ @@ -591,6 +591,9 @@ int pingval; } } + +extern unsigned long mysubnet; + /* * Find an nfs server for a host. */ @@ -653,13 +656,41 @@ mntfs *mf; * Get here if we can't find an entry */ if (hp) { + int i, j; + unsigned long tmpaddr; + switch (hp->h_addrtype) { case AF_INET: ip = ALLOC(sockaddr_in); bzero((voidp) ip, sizeof(*ip)); ip->sin_family = AF_INET; - bcopy((voidp) hp->h_addr, (voidp) &ip->sin_addr, sizeof(ip->sin_addr)); - + /* + * pick host address that is on the same subnet + * as mysubnet if possible; otherwise, pick the first + * one. + */ + for (i=0; hp->h_addr_list[i]; i++) { + bcopy ((voidp)hp->h_addr_list[i], (voidp)&tmpaddr, + sizeof(tmpaddr)); + for (j=0; j < 4; j++) { + if ((0xff & (mysubnet >> 8*j)) == 0) continue; + if ((0xff & (mysubnet >> 8*j)) != + (0xff & (tmpaddr >> 8*j))) break; + } + if (j == 4) { + + /* we found a matching subnet address */ + break; + } + } + if (!hp->h_addr_list[i]) { + /* no interface matching current subnet; pick one */ + bcopy((voidp) hp->h_addr, (voidp) &ip->sin_addr, sizeof(ip->sin_addr)); + } + else { + /* we found a matching subnet interface */ + bcopy((voidp) hp->h_addr_list[i], (voidp) &ip->sin_addr, sizeof(ip->sin_addr)); + } ip->sin_port = htons(NFS_PORT); break; diff --git a/usr.sbin/amd/amd/wire.c b/usr.sbin/amd/amd/wire.c index 340a284abba..a31e0f630fb 100644 --- a/usr.sbin/amd/amd/wire.c +++ b/usr.sbin/amd/amd/wire.c @@ -37,7 +37,7 @@ * * @(#)wire.c 8.1 (Berkeley) 6/6/93 * - * $Id$ + * $Id: wire.c,v 1.4 1997/02/22 16:01:46 peter Exp $ * */ @@ -85,6 +85,8 @@ static addrlist *localnets = 0; #define clist (ifc.ifc_ifcu.ifcu_req) #define count (ifc.ifc_len/sizeof(struct ifreq)) +extern unsigned long mysubnet; + char *getwire P((void)); char *getwire() { @@ -136,6 +138,8 @@ char *getwire() /* * Scan the list looking for a suitable interface */ + mysubnet = 0; + for (cp = buf; cp < cplim; cp += size(ifr)) { addrlist *al; ifr = (struct ifreq *) cp; @@ -227,10 +231,13 @@ char *getwire() /* This is probably very wrong. */ np = getnetbyaddr(subnet, AF_INET); #endif /* IN_CLASSA */ - if (np) + if (np) { s = np->n_name; + mysubnet = np->n_net; + } else { subnet = address & netmask; + mysubnet = subnet; hp = gethostbyaddr((char *) &subnet, 4, AF_INET); if (hp) s = hp->h_name;