Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route/route_ctl.c
Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | struct rib_subscription { | ||||
void *arg; | void *arg; | ||||
enum rib_subscription_type type; | enum rib_subscription_type type; | ||||
struct epoch_context epoch_ctx; | struct epoch_context epoch_ctx; | ||||
}; | }; | ||||
static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type, | static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type, | ||||
struct rib_cmd_info *rc); | struct rib_cmd_info *rc); | ||||
static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info); | |||||
static void destroy_subscription_epoch(epoch_context_t ctx); | static void destroy_subscription_epoch(epoch_context_t ctx); | ||||
static struct rib_head * | static struct rib_head * | ||||
get_rnh(uint32_t fibnum, const struct rt_addrinfo *info) | get_rnh(uint32_t fibnum, const struct rt_addrinfo *info) | ||||
{ | { | ||||
struct rib_head *rnh; | struct rib_head *rnh; | ||||
struct sockaddr *dst; | struct sockaddr *dst; | ||||
▲ Show 20 Lines • Show All 179 Lines • ▼ Show 20 Lines | if (rt_old != NULL) { | ||||
rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | ||||
} | } | ||||
} | } | ||||
RIB_WUNLOCK(rnh); | RIB_WUNLOCK(rnh); | ||||
if ((rn != NULL) || (rt_old != NULL)) | if ((rn != NULL) || (rt_old != NULL)) | ||||
rib_notify(rnh, RIB_NOTIFY_DELAYED, rc); | rib_notify(rnh, RIB_NOTIFY_DELAYED, rc); | ||||
if (rt_old != NULL) { | |||||
rt_notifydelete(rt_old, info); | |||||
rtfree(rt_old); | |||||
} | |||||
/* | /* | ||||
* If it still failed to go into the tree, | * If it still failed to go into the tree, | ||||
* then un-make it (this should be a function) | * then un-make it (this should be a function) | ||||
*/ | */ | ||||
if (rn == NULL) { | if (rn == NULL) { | ||||
nhop_free(nh); | nhop_free(nh); | ||||
uma_zfree(V_rtzone, rt); | uma_zfree(V_rtzone, rt); | ||||
return (EEXIST); | return (EEXIST); | ||||
} | } | ||||
/* | |||||
* If this protocol has something to add to this then | |||||
* allow it to do that as well. | |||||
*/ | |||||
if (ifa->ifa_rtrequest) | |||||
ifa->ifa_rtrequest(RTM_ADD, rt, rt->rt_nhop, info); | |||||
RT_UNLOCK(rt); | RT_UNLOCK(rt); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Removes route defined by @info from the kernel table specified by @fibnum and | * Removes route defined by @info from the kernel table specified by @fibnum and | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | if (rt != NULL) { | ||||
rc->rc_nh_old = rt->rt_nhop; | rc->rc_nh_old = rt->rt_nhop; | ||||
rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); | ||||
} | } | ||||
RIB_WUNLOCK(rnh); | RIB_WUNLOCK(rnh); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
rib_notify(rnh, RIB_NOTIFY_DELAYED, rc); | rib_notify(rnh, RIB_NOTIFY_DELAYED, rc); | ||||
rt_notifydelete(rt, info); | |||||
/* | /* | ||||
* If the caller wants it, then it can have it, | * If the caller wants it, then it can have it, | ||||
* the entry will be deleted after the end of the current epoch. | * the entry will be deleted after the end of the current epoch. | ||||
*/ | */ | ||||
rtfree(rt); | rtfree(rt); | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | if (rt->rt_nhop != nh_orig) { | ||||
nhop_free(nh); | nhop_free(nh); | ||||
return (EAGAIN); | return (EAGAIN); | ||||
} | } | ||||
/* Proceed with the update */ | /* Proceed with the update */ | ||||
RT_LOCK(rt); | RT_LOCK(rt); | ||||
/* Provide notification to the protocols.*/ | /* Provide notification to the protocols.*/ | ||||
if ((nh_orig->nh_ifa != nh->nh_ifa) && nh_orig->nh_ifa->ifa_rtrequest) | |||||
nh_orig->nh_ifa->ifa_rtrequest(RTM_DELETE, rt, nh_orig, info); | |||||
rt->rt_nhop = nh; | rt->rt_nhop = nh; | ||||
rt_setmetrics(info, rt); | rt_setmetrics(info, rt); | ||||
if ((nh_orig->nh_ifa != nh->nh_ifa) && nh_orig->nh_ifa->ifa_rtrequest) | |||||
nh_orig->nh_ifa->ifa_rtrequest(RTM_DELETE, rt, nh_orig, info); | |||||
/* Finalize notification */ | /* Finalize notification */ | ||||
rc->rc_rt = rt; | rc->rc_rt = rt; | ||||
rc->rc_nh_old = nh_orig; | rc->rc_nh_old = nh_orig; | ||||
rc->rc_nh_new = rt->rt_nhop; | rc->rc_nh_new = rt->rt_nhop; | ||||
RT_UNLOCK(rt); | RT_UNLOCK(rt); | ||||
/* Update generation id to reflect rtable change */ | /* Update generation id to reflect rtable change */ | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | rib_action(uint32_t fibnum, int action, struct rt_addrinfo *info, | ||||
default: | default: | ||||
error = ENOTSUP; | error = ENOTSUP; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static void | |||||
rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info) | |||||
{ | |||||
struct ifaddr *ifa; | |||||
/* | |||||
* give the protocol a chance to keep things in sync. | |||||
*/ | |||||
ifa = rt->rt_nhop->nh_ifa; | |||||
if (ifa != NULL && ifa->ifa_rtrequest != NULL) | |||||
ifa->ifa_rtrequest(RTM_DELETE, rt, rt->rt_nhop, info); | |||||
} | |||||
struct rt_delinfo | struct rt_delinfo | ||||
{ | { | ||||
struct rt_addrinfo info; | struct rt_addrinfo info; | ||||
struct rib_head *rnh; | struct rib_head *rnh; | ||||
struct rtentry *head; | struct rtentry *head; | ||||
struct rib_cmd_info rc; | struct rib_cmd_info rc; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | while (di.head != NULL) { | ||||
di.rc.rc_rt = rt; | di.rc.rc_rt = rt; | ||||
di.rc.rc_nh_old = rt->rt_nhop; | di.rc.rc_nh_old = rt->rt_nhop; | ||||
rib_notify(rnh, RIB_NOTIFY_DELAYED, &di.rc); | rib_notify(rnh, RIB_NOTIFY_DELAYED, &di.rc); | ||||
/* TODO std rt -> rt_addrinfo export */ | /* TODO std rt -> rt_addrinfo export */ | ||||
di.info.rti_info[RTAX_DST] = rt_key(rt); | di.info.rti_info[RTAX_DST] = rt_key(rt); | ||||
di.info.rti_info[RTAX_NETMASK] = rt_mask(rt); | di.info.rti_info[RTAX_NETMASK] = rt_mask(rt); | ||||
rt_notifydelete(rt, &di.info); | |||||
if (report) | if (report) | ||||
rt_routemsg(RTM_DELETE, rt, rt->rt_nhop->nh_ifp, 0, | rt_routemsg(RTM_DELETE, rt, rt->rt_nhop->nh_ifp, 0, | ||||
fibnum); | fibnum); | ||||
rtfree(rt); | rtfree(rt); | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
▲ Show 20 Lines • Show All 89 Lines • Show Last 20 Lines |