Index: sys/net/route.c =================================================================== --- sys/net/route.c +++ sys/net/route.c @@ -243,7 +243,7 @@ } RT_LOCK(rc.rc_rt); - flags = rc.rc_rt->rt_flags; + flags = rc.rc_rt->rte_flags; RT_UNLOCK(rc.rc_rt); RTSTAT_INC(rts_dynamic); @@ -354,6 +354,7 @@ struct nhop_object *nh; int sa_len; + nh = rt->rt_nhop; if (flags & NHR_COPY) { /* Copy destination if dst is non-zero */ src = rt_key(rt); @@ -383,9 +384,10 @@ } /* Copy gateway is set && dst is non-zero */ - src = &rt->rt_nhop->gw_sa; + src = &nh->gw_sa; dst = info->rti_info[RTAX_GATEWAY]; - if ((rt->rt_flags & RTF_GATEWAY) && src != NULL && dst != NULL){ + if ((nhop_get_rtflags(nh) & RTF_GATEWAY) && + src != NULL && dst != NULL) { if (src->sa_len > dst->sa_len) return (ENOMEM); memcpy(dst, src, src->sa_len); @@ -398,20 +400,19 @@ info->rti_info[RTAX_NETMASK] = rt_mask(rt); info->rti_addrs |= RTA_NETMASK; } - if (rt->rt_flags & RTF_GATEWAY) { - info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; + if (nhop_get_rtflags(nh) & RTF_GATEWAY) { + info->rti_info[RTAX_GATEWAY] = &nh->gw_sa; info->rti_addrs |= RTA_GATEWAY; } } - nh = rt->rt_nhop; rmx = info->rti_rmx; if (rmx != NULL) { info->rti_mflags |= RTV_MTU; rmx->rmx_mtu = nh->nh_mtu; } - info->rti_flags = rt->rt_flags | nhop_get_rtflags(nh); + info->rti_flags = rt->rte_flags | nhop_get_rtflags(nh); info->rti_ifp = nh->nh_ifp; info->rti_ifa = nh->nh_ifa; if (flags & NHR_REF) { @@ -579,7 +580,7 @@ * Protect (sorta) against walktree recursion problems * with cloned routes */ - if ((rt->rt_flags & RTF_UP) == 0) + if ((rt->rte_flags & RTF_UP) == 0) return (0); return (1); Index: sys/net/route/route_ctl.c =================================================================== --- sys/net/route/route_ctl.c +++ sys/net/route/route_ctl.c @@ -251,7 +251,7 @@ return (ENOBUFS); } RT_LOCK_INIT(rt); - rt->rt_flags = RTF_UP | flags; + rt->rte_flags = RTF_UP | flags; rt->rt_nhop = nh; /* Fill in dst */ @@ -406,6 +406,7 @@ { struct sockaddr *dst, *netmask; struct rtentry *rt; + struct nhop_object *nh; struct radix_node *rn; dst = info->rti_info[RTAX_DST]; @@ -417,16 +418,18 @@ return (NULL); } + nh = rt->rt_nhop; + if ((info->rti_flags & RTF_PINNED) == 0) { /* Check if target route can be deleted */ - if (rt->rt_flags & RTF_PINNED) { + if (NH_IS_PINNED(nh)) { *perror = EADDRINUSE; return (NULL); } } if (info->rti_filter != NULL) { - if (info->rti_filter(rt, rt->rt_nhop, info->rti_filterdata)==0){ + if (info->rti_filter(rt, nh, info->rti_filterdata)==0){ /* Not matched */ *perror = ENOENT; return (NULL); @@ -437,7 +440,7 @@ * Ease the caller work by filling in remaining info * from that particular entry. */ - info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; + info->rti_info[RTAX_GATEWAY] = &nh->gw_sa; } /* @@ -459,7 +462,7 @@ rt = RNTORT(rn); RT_LOCK(rt); - rt->rt_flags &= ~RTF_UP; + rt->rte_flags &= ~RTF_UP; *perror = 0; Index: sys/net/route/route_ddb.c =================================================================== --- sys/net/route/route_ddb.c +++ sys/net/route/route_ddb.c @@ -148,18 +148,17 @@ } db_printf("flags "); - flags = rt->rt_flags; + flags = rt->rte_flags | nhop_get_rtflags(nh); if (flags == 0) db_printf("none"); while ((idx = ffs(flags)) > 0) { idx--; - if (flags != rt->rt_flags) - db_printf(","); db_printf("%s", rt_flag_name(idx)); - flags &= ~(1ul << idx); + if (flags != 0) + db_printf(","); } db_printf("\n"); Index: sys/net/route/route_var.h =================================================================== --- sys/net/route/route_var.h +++ sys/net/route/route_var.h @@ -165,7 +165,7 @@ char rt_dstb[28]; }; - int rt_flags; /* up/down?, host/net */ + int rte_flags; /* up/down?, host/net */ u_long rt_weight; /* absolute weight */ u_long rt_expire; /* lifetime for route, e.g. redirect */ #define rt_endzero rt_mtx Index: sys/net/rtsock.c =================================================================== --- sys/net/rtsock.c +++ sys/net/rtsock.c @@ -179,7 +179,8 @@ 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, ...); -static void rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out); +static void rt_getmetrics(const struct rtentry *rt, + const struct nhop_object *nh, struct rt_metrics *out); static void rt_dispatch(struct mbuf *, sa_family_t); static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum, struct rt_msghdr *rtm, struct rib_cmd_info *rc); @@ -814,12 +815,12 @@ w.w_tmemsize = alloc_len; rtsock_msg_buffer(rtm->rtm_type, info, &w, &len); - if (rt->rt_flags & RTF_GWFLAG_COMPAT) + if (rt->rte_flags & RTF_GWFLAG_COMPAT) rtm->rtm_flags = RTF_GATEWAY | - (rt->rt_flags & ~RTF_GWFLAG_COMPAT); + (rt->rte_flags & ~RTF_GWFLAG_COMPAT); else - rtm->rtm_flags = rt->rt_flags; - rt_getmetrics(rt, &rtm->rtm_rmx); + rtm->rtm_flags = rt->rte_flags; + rt_getmetrics(rt, nh, &rtm->rtm_rmx); rtm->rtm_addrs = info->rti_addrs; if (orig_rtm != NULL) @@ -1055,13 +1056,14 @@ static void -rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out) +rt_getmetrics(const struct rtentry *rt, const struct nhop_object *nh, + struct rt_metrics *out) { bzero(out, sizeof(*out)); - out->rmx_mtu = rt->rt_nhop->nh_mtu; + out->rmx_mtu = nh->nh_mtu; out->rmx_weight = rt->rt_weight; - out->rmx_nhidx = nhop_get_idx(rt->rt_nhop); + out->rmx_nhidx = nhop_get_idx(nh); /* Kernel -> userland timebase conversion. */ out->rmx_expire = rt->rt_expire ? rt->rt_expire - time_uptime + time_second : 0; @@ -1472,15 +1474,17 @@ { struct sockaddr_storage ss; struct rt_addrinfo info; + struct nhop_object *nh; if (V_route_cb.any_count == 0) return (0); + nh = rt->rt_nhop; bzero((caddr_t)&info, sizeof(info)); info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt), rt_mask(rt), &ss); - info.rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; - info.rti_flags = rt->rt_flags; + info.rti_info[RTAX_GATEWAY] = &nh->gw_sa; + info.rti_flags = rt->rte_flags | nhop_get_rtflags(nh); info.rti_ifp = ifp; return (rtsock_routemsg_info(cmd, &info, fibnum)); @@ -1681,7 +1685,7 @@ can_export_rte(struct ucred *td_ucred, const struct rtentry *rt) { - if ((rt->rt_flags & RTF_HOST) == 0 + if ((rt->rte_flags & RTF_HOST) == 0 ? jailed_without_vnet(td_ucred) : prison_if(td_ucred, rt_key_const(rt)) != 0) return (0); @@ -1703,17 +1707,17 @@ NET_EPOCH_ASSERT(); - if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) + if (w->w_op == NET_RT_FLAGS && !(rt->rte_flags & w->w_arg)) return 0; if (!can_export_rte(w->w_req->td->td_ucred, rt)) return (0); + nh = rt->rt_nhop; bzero((caddr_t)&info, sizeof(info)); info.rti_info[RTAX_DST] = rt_key(rt); - info.rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; + info.rti_info[RTAX_GATEWAY] = &nh->gw_sa; info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt), rt_mask(rt), &ss); info.rti_info[RTAX_GENMASK] = 0; - nh = rt->rt_nhop; if (nh->nh_ifp && !(nh->nh_ifp->if_flags & IFF_DYING)) { info.rti_info[RTAX_IFP] = nh->nh_ifp->if_addr->ifa_addr; info.rti_info[RTAX_IFA] = nh->nh_ifa->ifa_addr; @@ -1727,13 +1731,13 @@ bzero(&rtm->rtm_index, sizeof(*rtm) - offsetof(struct rt_msghdr, rtm_index)); - if (rt->rt_flags & RTF_GWFLAG_COMPAT) + if (rt->rte_flags & RTF_GWFLAG_COMPAT) rtm->rtm_flags = RTF_GATEWAY | - (rt->rt_flags & ~RTF_GWFLAG_COMPAT); + (rt->rte_flags & ~RTF_GWFLAG_COMPAT); else - rtm->rtm_flags = rt->rt_flags; + rtm->rtm_flags = rt->rte_flags; rtm->rtm_flags |= nhop_get_rtflags(nh); - rt_getmetrics(rt, &rtm->rtm_rmx); + rt_getmetrics(rt, nh, &rtm->rtm_rmx); rtm->rtm_index = nh->nh_ifp->if_index; rtm->rtm_addrs = info.rti_addrs; error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);