Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Jan 2016 09:05:14 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r294084 - in head/sys/fs: nfs nfsclient
Message-ID:  <201601150905.u0F95Em4061256@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Fri Jan 15 09:05:14 2016
New Revision: 294084
URL: https://svnweb.freebsd.org/changeset/base/294084

Log:
  Make nfscl_getmyip() use new routing KPI.
  
  * Use standard IPv6 SAS instead of rt->rt_ifa address.
  * Make address lookup work for IPv6 LLA.
  * Save address into buffer provided by caller instead of using static vars.
  
  Discussed with:	rmacklem

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsclient/nfs_clport.c
  head/sys/fs/nfsclient/nfs_clrpcops.c

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Fri Jan 15 09:01:53 2016	(r294083)
+++ head/sys/fs/nfs/nfs_var.h	Fri Jan 15 09:05:14 2016	(r294084)
@@ -306,7 +306,7 @@ void nfscl_reqstart(struct nfsrv_descrip
 nfsuint64 *nfscl_getcookie(struct nfsnode *, off_t off, int);
 void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *,
       vnode_t, int, u_int32_t);
-u_int8_t *nfscl_getmyip(struct nfsmount *, int *);
+u_int8_t *nfscl_getmyip(struct nfsmount *, struct in6_addr *, int *);
 int nfsm_getfh(struct nfsrv_descript *, struct nfsfh **);
 int nfscl_mtofh(struct nfsrv_descript *, struct nfsfh **,
         struct nfsvattr *, int *);

Modified: head/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clport.c	Fri Jan 15 09:01:53 2016	(r294083)
+++ head/sys/fs/nfsclient/nfs_clport.c	Fri Jan 15 09:05:14 2016	(r294084)
@@ -34,6 +34,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_inet.h"
 #include "opt_inet6.h"
 
 #include <sys/capsicum.h>
@@ -46,7 +47,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/hash.h>
 #include <sys/sysctl.h>
 #include <fs/nfs/nfsport.h>
+#include <netinet/in_fib.h>
 #include <netinet/if_ether.h>
+#include <netinet6/ip6_var.h>
 #include <net/if_types.h>
 
 #include <fs/nfsclient/nfs_kdtrace.h>
@@ -1038,73 +1041,66 @@ nfscl_loadfsinfo(struct nfsmount *nmp, s
 }
 
 /*
- * Get a pointer to my IP addrress and return it.
- * Return NULL if you can't find one.
+ * Lookups source address which should be used to communicate with
+ * @nmp and stores it inside @pdst.
+ *
+ * Returns 0 on success.
  */
 u_int8_t *
-nfscl_getmyip(struct nfsmount *nmp, int *isinet6p)
+nfscl_getmyip(struct nfsmount *nmp, struct in6_addr *paddr, int *isinet6p)
 {
-	struct sockaddr_in sad, *sin;
-	struct rtentry *rt;
-	u_int8_t *retp = NULL;
-	static struct in_addr laddr;
+	int error, fibnum;
 
-	*isinet6p = 0;
-	/*
-	 * Loop up a route for the destination address.
-	 */
+	fibnum = curthread->td_proc->p_fibnum;
+
+#ifdef INET
 	if (nmp->nm_nam->sa_family == AF_INET) {
-		bzero(&sad, sizeof (sad));
+		struct sockaddr_in *sin;
+		struct nhop4_extended nh_ext;
+
 		sin = (struct sockaddr_in *)nmp->nm_nam;
-		sad.sin_family = AF_INET;
-		sad.sin_len = sizeof (struct sockaddr_in);
-		sad.sin_addr.s_addr = sin->sin_addr.s_addr;
 		CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
-		rt = rtalloc1_fib((struct sockaddr *)&sad, 0, 0UL,
-		     curthread->td_proc->p_fibnum);
-		if (rt != NULL) {
-			if (rt->rt_ifp != NULL &&
-			    rt->rt_ifa != NULL &&
-			    ((rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) &&
-			    rt->rt_ifa->ifa_addr->sa_family == AF_INET) {
-				sin = (struct sockaddr_in *)
-				    rt->rt_ifa->ifa_addr;
-				laddr.s_addr = sin->sin_addr.s_addr;
-				retp = (u_int8_t *)&laddr;
-			}
-			RTFREE_LOCKED(rt);
-		}
+		error = fib4_lookup_nh_ext(fibnum, sin->sin_addr, 0, 0,
+		    &nh_ext);
 		CURVNET_RESTORE();
+		if (error != 0)
+			return (NULL);
+
+		if ((ntohl(nh_ext.nh_src.s_addr) >> IN_CLASSA_NSHIFT) ==
+		    IN_LOOPBACKNET) {
+			/* Ignore loopback addresses */
+			return (NULL);
+		}
+
+		*isinet6p = 0;
+		*((struct in_addr *)paddr) = nh_ext.nh_src;
+
+		return (u_int8_t *)paddr;
+	}
+#endif
 #ifdef INET6
-	} else if (nmp->nm_nam->sa_family == AF_INET6) {
-		struct sockaddr_in6 sad6, *sin6;
-		static struct in6_addr laddr6;
+	if (nmp->nm_nam->sa_family == AF_INET6) {
+		struct sockaddr_in6 *sin6;
 
-		bzero(&sad6, sizeof (sad6));
 		sin6 = (struct sockaddr_in6 *)nmp->nm_nam;
-		sad6.sin6_family = AF_INET6;
-		sad6.sin6_len = sizeof (struct sockaddr_in6);
-		sad6.sin6_addr = sin6->sin6_addr;
+
 		CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
-		rt = rtalloc1_fib((struct sockaddr *)&sad6, 0, 0UL,
-		     curthread->td_proc->p_fibnum);
-		if (rt != NULL) {
-			if (rt->rt_ifp != NULL &&
-			    rt->rt_ifa != NULL &&
-			    ((rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) &&
-			    rt->rt_ifa->ifa_addr->sa_family == AF_INET6) {
-				sin6 = (struct sockaddr_in6 *)
-				    rt->rt_ifa->ifa_addr;
-				laddr6 = sin6->sin6_addr;
-				retp = (u_int8_t *)&laddr6;
-				*isinet6p = 1;
-			}
-			RTFREE_LOCKED(rt);
-		}
+		error = in6_selectsrc_addr(fibnum, &sin6->sin6_addr,
+		    sin6->sin6_scope_id, NULL, paddr, NULL);
 		CURVNET_RESTORE();
-#endif
+		if (error != 0)
+			return (NULL);
+
+		if (IN6_IS_ADDR_LOOPBACK(paddr))
+			return (NULL);
+
+		/* Scope is embedded in */
+		*isinet6p = 1;
+
+		return (u_int8_t *)paddr;
 	}
-	return (retp);
+#endif
+	return (NULL);
 }
 
 /*

Modified: head/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clrpcops.c	Fri Jan 15 09:01:53 2016	(r294083)
+++ head/sys/fs/nfsclient/nfs_clrpcops.c	Fri Jan 15 09:05:14 2016	(r294084)
@@ -829,6 +829,7 @@ nfsrpc_setclient(struct nfsmount *nmp, s
 	u_int32_t lease;
 	static u_int32_t rev = 0;
 	struct nfsclds *dsp, *ndsp, *tdsp;
+	struct in6_addr a6;
 
 	if (nfsboottime.tv_sec == 0)
 		NFSSETBOOTTIME(nfsboottime);
@@ -889,7 +890,7 @@ nfsrpc_setclient(struct nfsmount *nmp, s
 	*tl = txdr_unsigned(NFS_CALLBCKPROG);
 	callblen = strlen(nfsv4_callbackaddr);
 	if (callblen == 0)
-		cp = nfscl_getmyip(nmp, &isinet6);
+		cp = nfscl_getmyip(nmp, &a6, &isinet6);
 	if (nfscl_enablecallb && nfs_numnfscbd > 0 &&
 	    (callblen > 0 || cp != NULL)) {
 		port = htons(nfsv4_cbport);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601150905.u0F95Em4061256>