Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route/route_ctl.c
Show First 20 Lines • Show All 410 Lines • ▼ Show 20 Lines | rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr, | ||||
dst = (const struct sockaddr_in6 *)rt_mask_const(rt); | dst = (const struct sockaddr_in6 *)rt_mask_const(rt); | ||||
if (dst == NULL) | if (dst == NULL) | ||||
memset(pmask, 0xFF, sizeof(struct in6_addr)); | memset(pmask, 0xFF, sizeof(struct in6_addr)); | ||||
else | else | ||||
*pmask = dst->sin6_addr; | *pmask = dst->sin6_addr; | ||||
} | } | ||||
#endif | #endif | ||||
static void | |||||
rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info) | |||||
{ | |||||
/* Kernel -> userland timebase conversion. */ | |||||
if (info->rti_mflags & RTV_EXPIRE) | |||||
rt->rt_expire = info->rti_rmx->rmx_expire ? | |||||
info->rti_rmx->rmx_expire - time_second + time_uptime : 0; | |||||
} | |||||
/* | /* | ||||
* Check if specified @gw matches gw data in the nexthop @nh. | * Check if specified @gw matches gw data in the nexthop @nh. | ||||
* | * | ||||
* Returns true if matches, false otherwise. | * Returns true if matches, false otherwise. | ||||
*/ | */ | ||||
bool | bool | ||||
match_nhop_gw(const struct nhop_object *nh, const struct sockaddr *gw) | match_nhop_gw(const struct nhop_object *nh, const struct sockaddr *gw) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | if (netmask) { | ||||
bcopy(dst, ndst, dst->sa_len); | bcopy(dst, ndst, dst->sa_len); | ||||
/* | /* | ||||
* We use the ifa reference returned by rt_getifa_fib(). | * We use the ifa reference returned by rt_getifa_fib(). | ||||
* This moved from below so that rnh->rnh_addaddr() can | * This moved from below so that rnh->rnh_addaddr() can | ||||
* examine the ifa and ifa->ifa_ifp if it so desires. | * examine the ifa and ifa->ifa_ifp if it so desires. | ||||
*/ | */ | ||||
rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT); | rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT); | ||||
rt_set_expire_info(rt, info); | |||||
*prt = rt; | *prt = rt; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
add_route(struct rib_head *rnh, struct rt_addrinfo *info, | add_route(struct rib_head *rnh, struct rt_addrinfo *info, | ||||
struct rib_cmd_info *rc) | struct rib_cmd_info *rc) | ||||
▲ Show 20 Lines • Show All 393 Lines • ▼ Show 20 Lines | add_route_nhop(struct rib_head *rnh, struct rtentry *rt, | ||||
ndst = (struct sockaddr *)rt_key(rt); | ndst = (struct sockaddr *)rt_key(rt); | ||||
netmask = info->rti_info[RTAX_NETMASK]; | netmask = info->rti_info[RTAX_NETMASK]; | ||||
rt->rt_nhop = rnd->rnd_nhop; | rt->rt_nhop = rnd->rnd_nhop; | ||||
rt->rt_weight = rnd->rnd_weight; | rt->rt_weight = rnd->rnd_weight; | ||||
rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes); | rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes); | ||||
if (rn != NULL) { | if (rn != NULL) { | ||||
if (rt->rt_expire > 0) | if (!NH_IS_NHGRP(rnd->rnd_nhop) && nhop_get_expire(rnd->rnd_nhop)) | ||||
tmproutes_update(rnh, rt); | tmproutes_update(rnh, rt, rnd->rnd_nhop); | ||||
/* Finalize notification */ | /* Finalize notification */ | ||||
rib_bump_gen(rnh); | rib_bump_gen(rnh); | ||||
rnh->rnh_prefixes++; | rnh->rnh_prefixes++; | ||||
rc->rc_cmd = RTM_ADD; | rc->rc_cmd = RTM_ADD; | ||||
rc->rc_rt = rt; | rc->rc_rt = rt; | ||||
rc->rc_nh_old = NULL; | rc->rc_nh_old = NULL; | ||||
rc->rc_nh_new = rnd->rnd_nhop; | rc->rc_nh_new = rnd->rnd_nhop; | ||||
rc->rc_nh_weight = rnd->rnd_weight; | rc->rc_nh_weight = rnd->rnd_weight; | ||||
rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | ||||
} else { | } else { | ||||
/* Existing route or memory allocation failure */ | /* Existing route or memory allocation failure */ | ||||
error = EEXIST; | error = EEXIST; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Switch @rt nhop/weigh to the ones specified in @rnd. | * Switch @rt nhop/weigh to the ones specified in @rnd. | ||||
* Conditionally set rt_expire if set in @info. | |||||
* Returns 0 on success. | * Returns 0 on success. | ||||
*/ | */ | ||||
int | int | ||||
change_route_nhop(struct rib_head *rnh, struct rtentry *rt, | change_route_nhop(struct rib_head *rnh, struct rtentry *rt, | ||||
struct rt_addrinfo *info, struct route_nhop_data *rnd, | struct rt_addrinfo *info, struct route_nhop_data *rnd, | ||||
struct rib_cmd_info *rc) | struct rib_cmd_info *rc) | ||||
{ | { | ||||
struct nhop_object *nh_orig; | struct nhop_object *nh_orig; | ||||
RIB_WLOCK_ASSERT(rnh); | RIB_WLOCK_ASSERT(rnh); | ||||
nh_orig = rt->rt_nhop; | nh_orig = rt->rt_nhop; | ||||
if (rnd->rnd_nhop != NULL) { | if (rnd->rnd_nhop != NULL) { | ||||
/* Changing expiration & nexthop & weight to a new one */ | /* Changing nexthop & weight to a new one */ | ||||
rt_set_expire_info(rt, info); | |||||
rt->rt_nhop = rnd->rnd_nhop; | rt->rt_nhop = rnd->rnd_nhop; | ||||
rt->rt_weight = rnd->rnd_weight; | rt->rt_weight = rnd->rnd_weight; | ||||
if (rt->rt_expire > 0) | if (!NH_IS_NHGRP(rnd->rnd_nhop) && nhop_get_expire(rnd->rnd_nhop)) | ||||
tmproutes_update(rnh, rt); | tmproutes_update(rnh, rt, rnd->rnd_nhop); | ||||
} else { | } else { | ||||
/* Route deletion requested. */ | /* Route deletion requested. */ | ||||
struct sockaddr *ndst, *netmask; | struct sockaddr *ndst, *netmask; | ||||
struct radix_node *rn; | struct radix_node *rn; | ||||
ndst = (struct sockaddr *)rt_key(rt); | ndst = (struct sockaddr *)rt_key(rt); | ||||
netmask = info->rti_info[RTAX_NETMASK]; | netmask = info->rti_info[RTAX_NETMASK]; | ||||
rn = rnh->rnh_deladdr(ndst, netmask, &rnh->head); | rn = rnh->rnh_deladdr(ndst, netmask, &rnh->head); | ||||
▲ Show 20 Lines • Show All 455 Lines • Show Last 20 Lines |