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:
Alexander V. Chernikov 2014-11-04 17:05:24 +00:00
parent 4003643db1
commit a9ac00b76b
5 changed files with 58 additions and 15 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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);
}
/*

View File

@ -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;

View File

@ -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 */