Convert in6p_lookup_mcast_ifp() to use new routing api.
* Add special fib6_lookup_nh_ifp() to return rt_ifp instead of rt_ifa->ifa_ifp for that.
This commit is contained in:
parent
4003643db1
commit
a9ac00b76b
@ -942,6 +942,48 @@ fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst,
|
||||
ia = ifatoia6(rte->rt_ifa);
|
||||
}
|
||||
|
||||
int
|
||||
fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
|
||||
uint32_t flowid, struct nhop6_basic *pnh6)
|
||||
{
|
||||
struct radix_node_head *rnh;
|
||||
struct radix_node *rn;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct rtentry *rte;
|
||||
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
|
||||
/* Do not lookup link-local addresses in rtable */
|
||||
return (fib6_lla_to_nh_basic(dst, scopeid, pnh6));
|
||||
}
|
||||
|
||||
KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum"));
|
||||
rnh = rt_tables_get_rnh(fibnum, AF_INET6);
|
||||
if (rnh == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
/* Prepare lookup key */
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_addr = *dst;
|
||||
sin6.sin6_scope_id = scopeid;
|
||||
sa6_embedscope(&sin6, 0);
|
||||
|
||||
RADIX_NODE_HEAD_RLOCK(rnh);
|
||||
rn = rnh->rnh_matchaddr((void *)&sin6, rnh);
|
||||
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
|
||||
rte = RNTORT(rn);
|
||||
/* Ensure route & ifp is UP */
|
||||
if (RT_LINK_IS_UP(rte->rt_ifp)) {
|
||||
fib6_rte_to_nh_basic(rte, dst, pnh6);
|
||||
pnh6->nh_ifp = rte->rt_ifp;
|
||||
RADIX_NODE_HEAD_RUNLOCK(rnh);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
RADIX_NODE_HEAD_RUNLOCK(rnh);
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
|
||||
uint32_t flowid, struct nhop6_basic *pnh6)
|
||||
|
@ -208,6 +208,8 @@ void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4);
|
||||
#define NHOP_LOOKUP_REF 0x01
|
||||
|
||||
|
||||
int fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
|
||||
uint32_t flowid, struct nhop6_basic *pnh6);
|
||||
int fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr *dst,
|
||||
uint32_t scopeid, uint32_t flowid, struct nhop6_basic *pnh6);
|
||||
int fib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst,
|
||||
|
@ -69,6 +69,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet6/mld6_var.h>
|
||||
#include <netinet6/scope6_var.h>
|
||||
|
||||
#include <net/rt_nhops.h>
|
||||
|
||||
#ifndef KTR_MLD
|
||||
#define KTR_MLD KTR_INET6
|
||||
#endif
|
||||
@ -1770,26 +1772,22 @@ static struct ifnet *
|
||||
in6p_lookup_mcast_ifp(const struct inpcb *in6p,
|
||||
const struct sockaddr_in6 *gsin6)
|
||||
{
|
||||
struct route_in6 ro6;
|
||||
struct ifnet *ifp;
|
||||
struct nhop6_basic nh6;
|
||||
struct in6_addr dst;
|
||||
uint32_t scopeid;
|
||||
uint32_t fibnum;
|
||||
|
||||
KASSERT(in6p->inp_vflag & INP_IPV6,
|
||||
("%s: not INP_IPV6 inpcb", __func__));
|
||||
KASSERT(gsin6->sin6_family == AF_INET6,
|
||||
("%s: not AF_INET6 group", __func__));
|
||||
|
||||
ifp = NULL;
|
||||
memset(&ro6, 0, sizeof(struct route_in6));
|
||||
memcpy(&ro6.ro_dst, gsin6, sizeof(struct sockaddr_in6));
|
||||
rtalloc_ign_fib((struct route *)&ro6, 0,
|
||||
in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB);
|
||||
if (ro6.ro_rt != NULL) {
|
||||
ifp = ro6.ro_rt->rt_ifp;
|
||||
KASSERT(ifp != NULL, ("%s: null ifp", __func__));
|
||||
RTFREE(ro6.ro_rt);
|
||||
}
|
||||
in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid);
|
||||
fibnum = in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
|
||||
if (fib6_lookup_nh_ifp(fibnum, &dst, scopeid, 0, &nh6) != 0)
|
||||
return (NULL);
|
||||
|
||||
return (ifp);
|
||||
return (nh6.nh_ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -475,7 +475,8 @@ in6_getscope(struct in6_addr *in6)
|
||||
}
|
||||
|
||||
void
|
||||
in6_splitscope(struct in6_addr *src, struct in6_addr *dst, uint32_t *scopeid)
|
||||
in6_splitscope(const struct in6_addr *src, struct in6_addr *dst,
|
||||
uint32_t *scopeid)
|
||||
{
|
||||
uint32_t zoneid;
|
||||
|
||||
|
@ -64,7 +64,7 @@ int in6_clearscope(struct in6_addr *);
|
||||
uint16_t in6_getscope(struct in6_addr *);
|
||||
uint32_t in6_getscopezone(const struct ifnet *, int);
|
||||
struct ifnet* in6_getlinkifnet(uint32_t);
|
||||
void in6_splitscope(struct in6_addr *src, struct in6_addr *dst,
|
||||
void in6_splitscope(const struct in6_addr *src, struct in6_addr *dst,
|
||||
uint32_t *scopeid);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user