Index: sys/net/route/route_ctl.h =================================================================== --- sys/net/route/route_ctl.h +++ sys/net/route/route_ctl.h @@ -82,18 +82,42 @@ rib_walk_hook_f_t *hook_f, void *arg); void rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg); -struct route_nhop_data; +struct nhop_object; +struct nhgrp_object; +struct route_nhop_data { + union { + struct nhop_object *rnd_nhop; + struct nhgrp_object *rnd_nhgrp; + }; + uint32_t rnd_weight; +}; + const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family, const struct sockaddr *dst, const struct sockaddr *netmask, struct route_nhop_data *rnd); const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family, const struct sockaddr *dst, struct route_nhop_data *rnd); +/* rtentry accessors */ +#ifdef INET +struct in_addr; +void rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr, + int *plen); +void rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr, + struct in_addr *pmask); +#endif +#ifdef INET6 +struct in6_addr; +void rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr, + int *plen); +void rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr, + struct in6_addr *pmask); +#endif + /* Nexthops */ uint32_t nhops_get_count(struct rib_head *rh); /* Multipath */ -struct nhgrp_object; struct weightened_nhop; struct weightened_nhop *nhgrp_get_nhops(struct nhgrp_object *nhg, Index: sys/net/route/route_ctl.c =================================================================== --- sys/net/route/route_ctl.c +++ sys/net/route/route_ctl.c @@ -236,6 +236,84 @@ return (weight); } +#ifdef INET +void +rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr, int *plen) +{ + const struct sockaddr_in *dst; + + dst = (const struct sockaddr_in *)rt_key_const(rt); + KASSERT((dst->sin_family == AF_INET), + ("rt family is %d, not inet", dst->sin_family)); + *paddr = dst->sin_addr; + dst = (const struct sockaddr_in *)rt_mask_const(rt); + if (dst == NULL) + *plen = 32; + else + *plen = bitcount32(dst->sin_addr.s_addr); +} + +void +rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr, + struct in_addr *pmask) +{ + const struct sockaddr_in *dst; + + dst = (const struct sockaddr_in *)rt_key_const(rt); + KASSERT((dst->sin_family == AF_INET), + ("rt family is %d, not inet", dst->sin_family)); + *paddr = dst->sin_addr; + dst = (const struct sockaddr_in *)rt_mask_const(rt); + if (dst == NULL) + pmask->s_addr = INADDR_BROADCAST; + else + *pmask = dst->sin_addr; +} +#endif + +#ifdef INET6 +static int +inet6_get_plen(const struct in6_addr *addr) +{ + + return (bitcount32(addr->s6_addr32[0]) + bitcount32(addr->s6_addr32[1]) + + bitcount32(addr->s6_addr32[2]) + bitcount32(addr->s6_addr32[3])); +} + +void +rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr, int *plen) +{ + const struct sockaddr_in6 *dst; + + dst = (const struct sockaddr_in6 *)rt_key_const(rt); + KASSERT((dst->sin6_family == AF_INET6), + ("rt family is %d, not inet6", dst->sin6_family)); + *paddr = dst->sin6_addr; + dst = (const struct sockaddr_in6 *)rt_mask_const(rt); + if (dst == NULL) + *plen = 128; + else + *plen = inet6_get_plen(&dst->sin6_addr); +} + +void +rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr, + struct in6_addr *pmask) +{ + const struct sockaddr_in6 *dst; + + dst = (const struct sockaddr_in6 *)rt_key_const(rt); + KASSERT((dst->sin6_family == AF_INET6), + ("rt family is %d, not inet", dst->sin6_family)); + *paddr = dst->sin6_addr; + dst = (const struct sockaddr_in6 *)rt_mask_const(rt); + if (dst == NULL) + memset(pmask, 0xFF, sizeof(struct in6_addr)); + else + *pmask = dst->sin6_addr; +} +#endif + static void rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info) { Index: sys/net/route/route_var.h =================================================================== --- sys/net/route/route_var.h +++ sys/net/route/route_var.h @@ -205,14 +205,7 @@ void tmproutes_destroy(struct rib_head *rh); /* route_ctl.c */ -struct route_nhop_data { - union { - struct nhop_object *rnd_nhop; - struct nhgrp_object *rnd_nhgrp; - }; - uint32_t rnd_weight; -}; - +struct route_nhop_data; int change_route_nhop(struct rib_head *rnh, struct rtentry *rt, struct rt_addrinfo *info, struct route_nhop_data *rnd, struct rib_cmd_info *rc);