Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/in6_fib.c
Show First 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static void fib6_rte_to_nh_extended(struct rtentry *rte, | static void fib6_rte_to_nh_extended(struct rtentry *rte, | ||||
const struct in6_addr *dst, uint32_t flags, struct nhop6_extended *pnh6); | const struct in6_addr *dst, uint32_t flags, struct nhop6_extended *pnh6); | ||||
static void fib6_rte_to_nh_basic(struct rtentry *rte, const struct in6_addr *dst, | static void fib6_rte_to_nh_basic(struct rtentry *rte, const struct in6_addr *dst, | ||||
uint32_t flags, struct nhop6_basic *pnh6); | uint32_t flags, struct nhop6_basic *pnh6); | ||||
static struct ifnet *fib6_get_ifaifp(struct rtentry *rte); | static struct ifnet *fib6_get_ifaifp(struct rtentry *rte); | ||||
#define RNTORT(p) ((struct rtentry *)(p)) | |||||
#define FIB6_LOOKUP_KEY(a) (void *)(__containerof(a, struct sockaddr_in6, sin6_addr)) | |||||
/* | /* | ||||
* Gets real interface for the @rte. | * Gets real interface for the @rte. | ||||
* Returns rt_ifp for !IFF_LOOPBACK routers. | * Returns rt_ifp for !IFF_LOOPBACK routers. | ||||
* Extracts "real" address interface from interface address | * Extracts "real" address interface from interface address | ||||
* loopback routes. | * loopback routes. | ||||
*/ | */ | ||||
static struct ifnet * | static struct ifnet * | ||||
fib6_get_ifaifp(struct rtentry *rte) | fib6_get_ifaifp(struct rtentry *rte) | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
int | int | ||||
fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scopeid, | fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scopeid, | ||||
uint32_t flags, uint32_t flowid, struct nhop6_basic *pnh6) | uint32_t flags, uint32_t flowid, struct nhop6_basic *pnh6) | ||||
{ | { | ||||
RIB_RLOCK_TRACKER; | RIB_RLOCK_TRACKER; | ||||
struct rib_head *rh; | struct rib_head *rh; | ||||
struct radix_node *rn; | struct radix_node *rn; | ||||
struct sockaddr_in6 sin6; | struct in6_addr addr6; | ||||
struct rtentry *rte; | struct rtentry *rte; | ||||
KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum")); | KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum")); | ||||
rh = rt_tables_get_rnh(fibnum, AF_INET6); | rh = rt_tables_get_rnh(fibnum, AF_INET6); | ||||
if (rh == NULL) | if (rh == NULL) | ||||
return (ENOENT); | return (ENOENT); | ||||
/* Prepare lookup key */ | /* Prepare lookup key */ | ||||
memset(&sin6, 0, sizeof(sin6)); | addr6 = *dst; | ||||
sin6.sin6_addr = *dst; | |||||
sin6.sin6_len = sizeof(struct sockaddr_in6); | |||||
/* Assume scopeid is valid and embed it directly */ | /* Assume scopeid is valid and embed it directly */ | ||||
if (IN6_IS_SCOPE_LINKLOCAL(dst)) | if (IN6_IS_SCOPE_LINKLOCAL(dst)) | ||||
sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff); | addr6.s6_addr16[1] = htons(scopeid & 0xffff); | ||||
RIB_RLOCK(rh); | RIB_RLOCK(rh); | ||||
rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); | rn = rh->rnh_matchaddr(FIB6_LOOKUP_KEY(&addr6), &rh->head); | ||||
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { | if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { | ||||
rte = RNTORT(rn); | rte = RNTORT(rn); | ||||
/* Ensure route & ifp is UP */ | /* Ensure route & ifp is UP */ | ||||
if (RT_LINK_IS_UP(rte->rt_ifp)) { | if (RT_LINK_IS_UP(rte->rt_ifp)) { | ||||
fib6_rte_to_nh_basic(rte, &sin6.sin6_addr, flags, pnh6); | fib6_rte_to_nh_basic(rte, &addr6, flags, pnh6); | ||||
RIB_RUNLOCK(rh); | RIB_RUNLOCK(rh); | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
RIB_RUNLOCK(rh); | RIB_RUNLOCK(rh); | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
Show All 11 Lines | |||||
*/ | */ | ||||
int | int | ||||
fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid, | fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid, | ||||
uint32_t flags, uint32_t flowid, struct nhop6_extended *pnh6) | uint32_t flags, uint32_t flowid, struct nhop6_extended *pnh6) | ||||
{ | { | ||||
RIB_RLOCK_TRACKER; | RIB_RLOCK_TRACKER; | ||||
struct rib_head *rh; | struct rib_head *rh; | ||||
struct radix_node *rn; | struct radix_node *rn; | ||||
struct sockaddr_in6 sin6; | struct in6_addr addr6; | ||||
struct rtentry *rte; | struct rtentry *rte; | ||||
KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_ext: bad fibnum")); | KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_ext: bad fibnum")); | ||||
rh = rt_tables_get_rnh(fibnum, AF_INET6); | rh = rt_tables_get_rnh(fibnum, AF_INET6); | ||||
if (rh == NULL) | if (rh == NULL) | ||||
return (ENOENT); | return (ENOENT); | ||||
/* Prepare lookup key */ | /* Prepare lookup key */ | ||||
memset(&sin6, 0, sizeof(sin6)); | addr6 = *dst; | ||||
sin6.sin6_len = sizeof(struct sockaddr_in6); | |||||
sin6.sin6_addr = *dst; | |||||
/* Assume scopeid is valid and embed it directly */ | /* Assume scopeid is valid and embed it directly */ | ||||
if (IN6_IS_SCOPE_LINKLOCAL(dst)) | if (IN6_IS_SCOPE_LINKLOCAL(dst)) | ||||
sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff); | addr6.s6_addr16[1] = htons(scopeid & 0xffff); | ||||
RIB_RLOCK(rh); | RIB_RLOCK(rh); | ||||
rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); | rn = rh->rnh_matchaddr(FIB6_LOOKUP_KEY(&addr6), &rh->head); | ||||
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { | if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { | ||||
rte = RNTORT(rn); | rte = RNTORT(rn); | ||||
#ifdef RADIX_MPATH | #ifdef RADIX_MPATH | ||||
rte = rt_mpath_select(rte, flowid); | rte = rt_mpath_select(rte, flowid); | ||||
if (rte == NULL) { | if (rte == NULL) { | ||||
RIB_RUNLOCK(rh); | RIB_RUNLOCK(rh); | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
#endif | #endif | ||||
/* Ensure route & ifp is UP */ | /* Ensure route & ifp is UP */ | ||||
if (RT_LINK_IS_UP(rte->rt_ifp)) { | if (RT_LINK_IS_UP(rte->rt_ifp)) { | ||||
fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags, | fib6_rte_to_nh_extended(rte, &addr6, flags, | ||||
pnh6); | pnh6); | ||||
if ((flags & NHR_REF) != 0) { | if ((flags & NHR_REF) != 0) { | ||||
/* TODO: Do lwref on egress ifp's */ | /* TODO: Do lwref on egress ifp's */ | ||||
} | } | ||||
RIB_RUNLOCK(rh); | RIB_RUNLOCK(rh); | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 14 Lines |