Changeset View
Changeset View
Standalone View
Standalone View
sys/net/radix_mpath.c
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <net/radix.h> | #include <net/radix.h> | ||||
#include <net/radix_mpath.h> | #include <net/radix_mpath.h> | ||||
#include <sys/rmlock.h> | #include <sys/rmlock.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <net/route/nhop.h> | |||||
#include <net/route/shared.h> | |||||
#include <net/route_var.h> | #include <net/route_var.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
/* | /* | ||||
* give some jitter to hash, to avoid synchronization between routers | * give some jitter to hash, to avoid synchronization between routers | ||||
*/ | */ | ||||
static uint32_t hashjitter; | static uint32_t hashjitter; | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | if (rn_mpath_next((struct radix_node *)rte) == NULL) | ||||
return (rte); | return (rte); | ||||
return (rt_mpath_selectrte(rte, hash)); | return (rt_mpath_selectrte(rte, hash)); | ||||
} | } | ||||
void | void | ||||
rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) | rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) | ||||
{ | { | ||||
struct rtentry *rt; | struct rtentry *rt, *rt_tmp; | ||||
/* | /* | ||||
* XXX we don't attempt to lookup cached route again; what should | * XXX we don't attempt to lookup cached route again; what should | ||||
* be done for sendto(3) case? | * be done for sendto(3) case? | ||||
*/ | */ | ||||
if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP) | if (ro->ro_nh && RT_LINK_IS_UP(ro->ro_nh->nh_ifp)) | ||||
&& RT_LINK_IS_UP(ro->ro_rt->rt_ifp)) | |||||
return; | return; | ||||
ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum); | ro->ro_nh = NULL; | ||||
rt_tmp = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum); | |||||
/* if the route does not exist or it is not multipath, don't care */ | /* if the route does not exist or it is not multipath, don't care */ | ||||
if (ro->ro_rt == NULL) | if (rt_tmp == NULL) | ||||
return; | return; | ||||
if (rn_mpath_next((struct radix_node *)ro->ro_rt) == NULL) { | if (rn_mpath_next((struct radix_node *)rt_tmp) == NULL) { | ||||
RT_UNLOCK(ro->ro_rt); | ro->ro_nh = rt_tmp->rt_nhop; | ||||
nhop_ref_object(ro->ro_nh); | |||||
RT_UNLOCK(rt_tmp); | |||||
return; | return; | ||||
} | } | ||||
rt = rt_mpath_selectrte(ro->ro_rt, hash); | rt = rt_mpath_selectrte(rt_tmp, hash); | ||||
/* XXX try filling rt_gwroute and avoid unreachable gw */ | /* XXX try filling rt_gwroute and avoid unreachable gw */ | ||||
/* gw selection has failed - there must be only zero weight routes */ | /* gw selection has failed - there must be only zero weight routes */ | ||||
if (!rt) { | if (!rt) { | ||||
RT_UNLOCK(ro->ro_rt); | RT_UNLOCK(rt_tmp); | ||||
ro->ro_rt = NULL; | |||||
return; | return; | ||||
} | } | ||||
if (ro->ro_rt != rt) { | if (rt_tmp != rt) { | ||||
RTFREE_LOCKED(ro->ro_rt); | RTFREE_LOCKED(rt_tmp); | ||||
ro->ro_rt = rt; | ro->ro_nh = rt->rt_nhop; | ||||
RT_LOCK(ro->ro_rt); | nhop_ref_object(ro->ro_nh); | ||||
RT_ADDREF(ro->ro_rt); | } else | ||||
RT_UNLOCK(rt_tmp); | |||||
} | |||||
RT_UNLOCK(ro->ro_rt); | |||||
} | } | ||||
void | void | ||||
rt_mpath_init_rnh(struct rib_head *rnh) | rt_mpath_init_rnh(struct rib_head *rnh) | ||||
{ | { | ||||
rnh->rnh_multipath = 1; | rnh->rnh_multipath = 1; | ||||
} | } | ||||
Show All 9 Lines |