Rework part of routing code to reduce difference to D26449.
* Split rt_setmetrics into get_info_weight() and rt_set_expire_info(), as these two can be applied at different entities and at different times. * Start filling route weight in route change notifications * Pass flowid to UDP/raw IP route lookups * Rework nd6_subscription_cb() and sysctl_dumpentry() to prepare for the fact that rtentry can contain multiple nexthops. Differential Revision: https://reviews.freebsd.org/D26497
This commit is contained in:
parent
7b3286c189
commit
2259a03020
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365973
@ -848,18 +848,6 @@ rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info,
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt)
|
||||
{
|
||||
|
||||
if (info->rti_mflags & RTV_WEIGHT)
|
||||
rt->rt_weight = info->rti_rmx->rmx_weight;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void
|
||||
rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
|
||||
{
|
||||
|
@ -104,6 +104,10 @@ struct rt_metrics {
|
||||
/* lle state is exported in rmx_state rt_metrics field */
|
||||
#define rmx_state rmx_weight
|
||||
|
||||
/* default route weight */
|
||||
#define RT_DEFAULT_WEIGHT 1
|
||||
#define RT_MAX_WEIGHT 16777215 /* 3 bytes */
|
||||
|
||||
/*
|
||||
* Keep a generation count of routing table, incremented on route addition,
|
||||
* so we can invalidate caches. This is accessed without a lock, as precision
|
||||
|
@ -175,6 +175,32 @@ get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
|
||||
return (rnh);
|
||||
}
|
||||
|
||||
static int
|
||||
get_info_weight(const struct rt_addrinfo *info, uint32_t default_weight)
|
||||
{
|
||||
uint32_t weight;
|
||||
|
||||
if (info->rti_mflags & RTV_WEIGHT)
|
||||
weight = info->rti_rmx->rmx_weight;
|
||||
else
|
||||
weight = default_weight;
|
||||
/* Keep upper 1 byte for adm distance purposes */
|
||||
if (weight > RT_MAX_WEIGHT)
|
||||
weight = RT_MAX_WEIGHT;
|
||||
|
||||
return (weight);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@ -423,9 +449,8 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
|
||||
* examine the ifa and ifa->ifa_ifp if it so desires.
|
||||
*/
|
||||
ifa = info->rti_ifa;
|
||||
rt->rt_weight = 1;
|
||||
|
||||
rt_setmetrics(info, rt);
|
||||
rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
|
||||
rt_set_expire_info(rt, info);
|
||||
|
||||
*prt = rt;
|
||||
return (0);
|
||||
@ -815,7 +840,7 @@ change_route_nhop(struct rib_head *rnh, struct rtentry *rt,
|
||||
|
||||
if (rnd->rnd_nhop != NULL) {
|
||||
/* Changing expiration & nexthop & weight to a new one */
|
||||
rt_setmetrics(info, rt);
|
||||
rt_set_expire_info(rt, info);
|
||||
rt->rt_nhop = rnd->rnd_nhop;
|
||||
rt->rt_weight = rnd->rnd_weight;
|
||||
if (rt->rt_expire > 0)
|
||||
|
@ -115,7 +115,6 @@ _Static_assert(__offsetof(struct route, ro_dst) == __offsetof(_ro_new, _dst_new)
|
||||
struct rib_head *rt_tables_get_rnh(uint32_t table, sa_family_t family);
|
||||
void rt_mpath_init_rnh(struct rib_head *rnh);
|
||||
int rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum);
|
||||
void rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt);
|
||||
#ifdef RADIX_MPATH
|
||||
struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
|
||||
struct rt_addrinfo *info, struct rtentry *rto, int *perror);
|
||||
|
@ -175,6 +175,8 @@ static int rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo,
|
||||
static int rt_xaddrs(caddr_t cp, caddr_t cplim,
|
||||
struct rt_addrinfo *rtinfo);
|
||||
static int sysctl_dumpentry(struct radix_node *rn, void *vw);
|
||||
static int sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh,
|
||||
uint32_t weight, struct walkarg *w);
|
||||
static int sysctl_iflist(int af, struct walkarg *w);
|
||||
static int sysctl_ifmalist(int af, struct walkarg *w);
|
||||
static int route_output(struct mbuf *m, struct socket *so, ...);
|
||||
@ -740,6 +742,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
|
||||
}
|
||||
}
|
||||
rc->rc_nh_new = rc->rc_rt->rt_nhop;
|
||||
rc->rc_nh_weight = rc->rc_rt->rt_weight;
|
||||
RIB_RUNLOCK(rnh);
|
||||
|
||||
return (0);
|
||||
@ -1696,9 +1699,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
|
||||
struct walkarg *w = vw;
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
struct nhop_object *nh;
|
||||
int error = 0, size;
|
||||
struct rt_addrinfo info;
|
||||
struct sockaddr_storage ss;
|
||||
int error = 0;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
|
||||
@ -1707,6 +1708,20 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
|
||||
if (!can_export_rte(w->w_req->td->td_ucred, rt))
|
||||
return (0);
|
||||
nh = rt->rt_nhop;
|
||||
error = sysctl_dumpnhop(rt, nh, rt->rt_weight, w);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh, uint32_t weight,
|
||||
struct walkarg *w)
|
||||
{
|
||||
struct rt_addrinfo info;
|
||||
int error = 0, size;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
bzero((caddr_t)&info, sizeof(info));
|
||||
info.rti_info[RTAX_DST] = rt_key(rt);
|
||||
info.rti_info[RTAX_GATEWAY] = &nh->gw_sa;
|
||||
|
@ -512,7 +512,8 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
} else {
|
||||
struct nhop_object *nh;
|
||||
|
||||
nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE, 0);
|
||||
nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE,
|
||||
m->m_pkthdr.flowid);
|
||||
if (nh == NULL) {
|
||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
|
||||
/*
|
||||
|
@ -1570,25 +1570,30 @@ nd6_free_redirect(const struct llentry *ln)
|
||||
/*
|
||||
* Updates status of the default router route.
|
||||
*/
|
||||
void
|
||||
nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg)
|
||||
static void
|
||||
check_release_defrouter(struct rib_cmd_info *rc, void *_cbdata)
|
||||
{
|
||||
struct nd_defrouter *dr;
|
||||
struct nhop_object *nh;
|
||||
|
||||
if (rc->rc_cmd == RTM_DELETE) {
|
||||
nh = rc->rc_nh_old;
|
||||
nh = rc->rc_nh_old;
|
||||
|
||||
if (nh->nh_flags & NHF_DEFAULT) {
|
||||
dr = defrouter_lookup(&nh->gw6_sa.sin6_addr, nh->nh_ifp);
|
||||
if (dr != NULL) {
|
||||
dr->installed = 0;
|
||||
defrouter_rele(dr);
|
||||
}
|
||||
if ((nh != NULL) && (nh->nh_flags & NHF_DEFAULT)) {
|
||||
dr = defrouter_lookup(&nh->gw6_sa.sin6_addr, nh->nh_ifp);
|
||||
if (dr != NULL) {
|
||||
dr->installed = 0;
|
||||
defrouter_rele(dr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg)
|
||||
{
|
||||
|
||||
check_release_defrouter(rc, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user