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
This commit is contained in:
parent
b936cc8d73
commit
d3bf8f6486
@ -306,7 +306,7 @@ void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *,
|
||||
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 *);
|
||||
|
@ -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, struct nfsfsinfo *fsp)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
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);
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
#ifdef INET6
|
||||
} else if (nmp->nm_nam->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 sad6, *sin6;
|
||||
static struct in6_addr laddr6;
|
||||
struct sockaddr_in *sin;
|
||||
struct nhop4_extended nh_ext;
|
||||
|
||||
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;
|
||||
sin = (struct sockaddr_in *)nmp->nm_nam;
|
||||
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 = fib4_lookup_nh_ext(fibnum, sin->sin_addr, 0, 0,
|
||||
&nh_ext);
|
||||
CURVNET_RESTORE();
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
return (retp);
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (nmp->nm_nam->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)nmp->nm_nam;
|
||||
|
||||
CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
|
||||
error = in6_selectsrc_addr(fibnum, &sin6->sin6_addr,
|
||||
sin6->sin6_scope_id, NULL, paddr, NULL);
|
||||
CURVNET_RESTORE();
|
||||
if (error != 0)
|
||||
return (NULL);
|
||||
|
||||
if (IN6_IS_ADDR_LOOPBACK(paddr))
|
||||
return (NULL);
|
||||
|
||||
/* Scope is embedded in */
|
||||
*isinet6p = 1;
|
||||
|
||||
return (u_int8_t *)paddr;
|
||||
}
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -829,6 +829,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclclient *clp, int reclaim,
|
||||
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, struct nfsclclient *clp, int reclaim,
|
||||
*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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user