Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route.c
Show First 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | rib_add_redirect(u_int fibnum, struct sockaddr *dst, struct sockaddr *gateway, | ||||
/* Verify the allowed flag mask. */ | /* Verify the allowed flag mask. */ | ||||
KASSERT(((flags & ~(RTF_GATEWAY)) == 0), | KASSERT(((flags & ~(RTF_GATEWAY)) == 0), | ||||
("invalid redirect flags: %x", flags)); | ("invalid redirect flags: %x", flags)); | ||||
flags |= RTF_HOST | RTF_DYNAMIC; | flags |= RTF_HOST | RTF_DYNAMIC; | ||||
/* Get the best ifa for the given interface and gateway. */ | /* Get the best ifa for the given interface and gateway. */ | ||||
if ((ifa = ifaof_ifpforaddr(gateway, ifp)) == NULL) | if ((ifa = ifaof_ifpforaddr(gateway, ifp)) == NULL) | ||||
return (ENETUNREACH); | return (ENETUNREACH); | ||||
ifa_ref(ifa); | |||||
bzero(&info, sizeof(info)); | bzero(&info, sizeof(info)); | ||||
info.rti_info[RTAX_DST] = dst; | info.rti_info[RTAX_DST] = dst; | ||||
info.rti_info[RTAX_GATEWAY] = gateway; | info.rti_info[RTAX_GATEWAY] = gateway; | ||||
info.rti_ifa = ifa; | info.rti_ifa = ifa; | ||||
info.rti_ifp = ifp; | info.rti_ifp = ifp; | ||||
info.rti_flags = flags; | info.rti_flags = flags; | ||||
/* Setup route metrics to define expire time. */ | /* Setup route metrics to define expire time. */ | ||||
bzero(&rti_rmx, sizeof(rti_rmx)); | bzero(&rti_rmx, sizeof(rti_rmx)); | ||||
/* Set expire time as absolute. */ | /* Set expire time as absolute. */ | ||||
rti_rmx.rmx_expire = lifetime_sec + time_second; | rti_rmx.rmx_expire = lifetime_sec + time_second; | ||||
info.rti_mflags |= RTV_EXPIRE; | info.rti_mflags |= RTV_EXPIRE; | ||||
info.rti_rmx = &rti_rmx; | info.rti_rmx = &rti_rmx; | ||||
error = rib_action(fibnum, RTM_ADD, &info, &rc); | error = rib_action(fibnum, RTM_ADD, &info, &rc); | ||||
ifa_free(ifa); | |||||
if (error != 0) { | if (error != 0) { | ||||
/* TODO: add per-fib redirect stats. */ | /* TODO: add per-fib redirect stats. */ | ||||
return (error); | return (error); | ||||
} | } | ||||
RTSTAT_INC(rts_dynamic); | RTSTAT_INC(rts_dynamic); | ||||
▲ Show 20 Lines • Show All 277 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
rt_flushifroutes(struct ifnet *ifp) | rt_flushifroutes(struct ifnet *ifp) | ||||
{ | { | ||||
rib_foreach_table_walk_del(AF_UNSPEC, rt_ifdelroute, ifp); | rib_foreach_table_walk_del(AF_UNSPEC, rt_ifdelroute, ifp); | ||||
} | } | ||||
/* | /* | ||||
* Look up rt_addrinfo for a specific fib. Note that if rti_ifa is defined, | * Look up rt_addrinfo for a specific fib. | ||||
* it will be referenced so the caller must free it. | |||||
* | * | ||||
* Assume basic consistency checks are executed by callers: | * Assume basic consistency checks are executed by callers: | ||||
* RTAX_DST exists, if RTF_GATEWAY is set, RTAX_GATEWAY exists as well. | * RTAX_DST exists, if RTF_GATEWAY is set, RTAX_GATEWAY exists as well. | ||||
*/ | */ | ||||
int | int | ||||
rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) | rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) | ||||
{ | { | ||||
const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr; | const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr; | ||||
struct epoch_tracker et; | int error, flags; | ||||
int needref, error, flags; | |||||
dst = info->rti_info[RTAX_DST]; | dst = info->rti_info[RTAX_DST]; | ||||
gateway = info->rti_info[RTAX_GATEWAY]; | gateway = info->rti_info[RTAX_GATEWAY]; | ||||
ifpaddr = info->rti_info[RTAX_IFP]; | ifpaddr = info->rti_info[RTAX_IFP]; | ||||
ifaaddr = info->rti_info[RTAX_IFA]; | ifaaddr = info->rti_info[RTAX_IFA]; | ||||
flags = info->rti_flags; | flags = info->rti_flags; | ||||
/* | /* | ||||
* ifp may be specified by sockaddr_dl | * ifp may be specified by sockaddr_dl | ||||
* when protocol address is ambiguous. | * when protocol address is ambiguous. | ||||
*/ | */ | ||||
error = 0; | error = 0; | ||||
needref = (info->rti_ifa == NULL); | |||||
NET_EPOCH_ENTER(et); | |||||
/* If we have interface specified by the ifindex in the address, use it */ | /* If we have interface specified by the ifindex in the address, use it */ | ||||
if (info->rti_ifp == NULL && ifpaddr != NULL && | if (info->rti_ifp == NULL && ifpaddr != NULL && | ||||
ifpaddr->sa_family == AF_LINK) { | ifpaddr->sa_family == AF_LINK) { | ||||
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr; | const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr; | ||||
if (sdl->sdl_index != 0) | if (sdl->sdl_index != 0) | ||||
info->rti_ifp = ifnet_byindex(sdl->sdl_index); | info->rti_ifp = ifnet_byindex(sdl->sdl_index); | ||||
} | } | ||||
Show All 38 Lines | if (info->rti_ifp != NULL) { | ||||
info->rti_ifa = ifaof_ifpforaddr(gateway, info->rti_ifp); | info->rti_ifa = ifaof_ifpforaddr(gateway, info->rti_ifp); | ||||
} else if (dst != NULL && gateway != NULL) | } else if (dst != NULL && gateway != NULL) | ||||
info->rti_ifa = ifa_ifwithroute(flags, dst, gateway, | info->rti_ifa = ifa_ifwithroute(flags, dst, gateway, | ||||
fibnum); | fibnum); | ||||
else if (sa != NULL) | else if (sa != NULL) | ||||
info->rti_ifa = ifa_ifwithroute(flags, sa, sa, | info->rti_ifa = ifa_ifwithroute(flags, sa, sa, | ||||
fibnum); | fibnum); | ||||
} | } | ||||
if (needref && info->rti_ifa != NULL) { | if (info->rti_ifa != NULL) { | ||||
if (info->rti_ifp == NULL) | if (info->rti_ifp == NULL) | ||||
info->rti_ifp = info->rti_ifa->ifa_ifp; | info->rti_ifp = info->rti_ifa->ifa_ifp; | ||||
ifa_ref(info->rti_ifa); | |||||
} else | } else | ||||
error = ENETUNREACH; | error = ENETUNREACH; | ||||
NET_EPOCH_EXIT(et); | |||||
return (error); | return (error); | ||||
} | } | ||||
void | void | ||||
rt_updatemtu(struct ifnet *ifp) | rt_updatemtu(struct ifnet *ifp) | ||||
{ | { | ||||
struct rib_head *rnh; | struct rib_head *rnh; | ||||
int mtu; | int mtu; | ||||
▲ Show 20 Lines • Show All 155 Lines • Show Last 20 Lines |