svn commit: r368769 - head/sys/net
Ryan Libby
rlibby at freebsd.org
Tue Dec 22 20:45:25 UTC 2020
On Tue, Dec 22, 2020 at 10:31 AM Mateusz Guzik <mjguzik at gmail.com> wrote:
>
> this makes NOIP kernels fail to compile:
>
> /usr/src/sys/net/rtsock.c:802:11: error: unused variable 'scopeid'
> [-Werror,-Wunused-variable]
> uint32_t scopeid = 0;
>
>
Fix in progress: https://reviews.freebsd.org/D27730
> On 12/18/20, Alexander V. Chernikov <melifaro at freebsd.org> wrote:
> > Author: melifaro
> > Date: Fri Dec 18 22:00:57 2020
> > New Revision: 368769
> > URL: https://svnweb.freebsd.org/changeset/base/368769
> >
> > Log:
> > Switch direct rt fields access in rtsock.c to newly-create field
> > acessors.
> >
> > rtsock code was build around the assumption that each rtentry record
> > in the system radix tree is a ready-to-use sockaddr. This assumptions
> > turned out to be not quite true:
> > * masks have their length tweaked, so we have rtsock_fix_netmask() hack
> > * IPv6 addresses have their scope embedded, so we have another explicit
> > deembedding hack.
> >
> > Change the code to decouple rtentry internals from rtsock code using
> > newly-created rtentry accessors. This will allow to eventually eliminate
> > both of the hacks and change rtentry dst/mask format.
> >
> > Differential Revision: https://reviews.freebsd.org/D27451
> >
> > Modified:
> > head/sys/net/rtsock.c
> >
> > Modified: head/sys/net/rtsock.c
> > ==============================================================================
> > --- head/sys/net/rtsock.c Fri Dec 18 20:41:23 2020 (r368768)
> > +++ head/sys/net/rtsock.c Fri Dec 18 22:00:57 2020 (r368769)
> > @@ -158,10 +158,13 @@ MTX_SYSINIT(rtsock, &rtsock_mtx, "rtsock route_cb
> > lock
> > SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
> >
> > struct walkarg {
> > + int family;
> > int w_tmemsize;
> > int w_op, w_arg;
> > caddr_t w_tmem;
> > struct sysctl_req *w_req;
> > + struct sockaddr *dst;
> > + struct sockaddr *mask;
> > };
> >
> > static void rts_input(struct mbuf *m);
> > @@ -170,7 +173,7 @@ static int rtsock_msg_buffer(int type, struct rt_addri
> > struct walkarg *w, int *plen);
> > 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_dumpentry(struct rtentry *rt, 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);
> > @@ -187,7 +190,8 @@ static int update_rtm_from_rc(struct rt_addrinfo *info
> > static void send_rtm_reply(struct socket *so, struct rt_msghdr *rtm,
> > struct mbuf *m, sa_family_t saf, u_int fibnum,
> > int rtm_errno);
> > -static int can_export_rte(struct ucred *td_ucred, const struct rtentry
> > *rt);
> > +static bool can_export_rte(struct ucred *td_ucred, bool rt_is_host,
> > + const struct sockaddr *rt_dst);
> >
> > static struct netisr_handler rtsock_nh = {
> > .nh_name = "rtsock",
> > @@ -707,7 +711,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
> > return (ESRCH);
> > }
> >
> > - nh = select_nhop(rc->rc_rt->rt_nhop, info->rti_info[RTAX_GATEWAY]);
> > + nh = select_nhop(rt_get_raw_nhop(rc->rc_rt),
> > info->rti_info[RTAX_GATEWAY]);
> > if (nh == NULL) {
> > RIB_RUNLOCK(rnh);
> > return (ESRCH);
> > @@ -721,9 +725,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
> > */
> > if (rtm->rtm_flags & RTF_ANNOUNCE) {
> > struct sockaddr laddr;
> > - struct nhop_object *nh;
> >
> > - nh = rc->rc_rt->rt_nhop;
> > if (nh->nh_ifp != NULL &&
> > nh->nh_ifp->if_type == IFT_PROPVIRTUAL) {
> > struct ifaddr *ifa;
> > @@ -747,7 +749,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
> > RIB_RUNLOCK(rnh);
> > return (ESRCH);
> > }
> > - nh = select_nhop(rc->rc_rt->rt_nhop, info->rti_info[RTAX_GATEWAY]);
> > + nh = select_nhop(rt_get_raw_nhop(rc->rc_rt),
> > info->rti_info[RTAX_GATEWAY]);
> > if (nh == NULL) {
> > RIB_RUNLOCK(rnh);
> > return (ESRCH);
> > @@ -760,6 +762,66 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
> > return (0);
> > }
> >
> > +static void
> > +init_sockaddrs_family(int family, struct sockaddr *dst, struct sockaddr
> > *mask)
> > +{
> > +#ifdef INET
> > + if (family == AF_INET) {
> > + struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
> > + struct sockaddr_in *mask4 = (struct sockaddr_in *)mask;
> > +
> > + bzero(dst4, sizeof(struct sockaddr_in));
> > + bzero(mask4, sizeof(struct sockaddr_in));
> > +
> > + dst4->sin_family = AF_INET;
> > + dst4->sin_len = sizeof(struct sockaddr_in);
> > + mask4->sin_family = AF_INET;
> > + mask4->sin_len = sizeof(struct sockaddr_in);
> > + }
> > +#endif
> > +#ifdef INET6
> > + if (family == AF_INET6) {
> > + struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
> > + struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)mask;
> > +
> > + bzero(dst6, sizeof(struct sockaddr_in6));
> > + bzero(mask6, sizeof(struct sockaddr_in6));
> > +
> > + dst6->sin6_family = AF_INET6;
> > + dst6->sin6_len = sizeof(struct sockaddr_in6);
> > + mask6->sin6_family = AF_INET6;
> > + mask6->sin6_len = sizeof(struct sockaddr_in6);
> > + }
> > +#endif
> > +}
> > +
> > +static void
> > +export_rtaddrs(const struct rtentry *rt, struct sockaddr *dst,
> > + struct sockaddr *mask)
> > +{
> > + uint32_t scopeid = 0;
> > +#ifdef INET
> > + if (dst->sa_family == AF_INET) {
> > + struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
> > + struct sockaddr_in *mask4 = (struct sockaddr_in *)mask;
> > + rt_get_inet_prefix_pmask(rt, &dst4->sin_addr, &mask4->sin_addr,
> > + &scopeid);
> > + return;
> > + }
> > +#endif
> > +#ifdef INET6
> > + if (dst->sa_family == AF_INET6) {
> > + struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
> > + struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)mask;
> > + rt_get_inet6_prefix_pmask(rt, &dst6->sin6_addr, &mask6->sin6_addr,
> > + &scopeid);
> > + dst6->sin6_scope_id = scopeid;
> > + return;
> > + }
> > +#endif
> > +}
> > +
> > +
> > /*
> > * Update sockaddrs, flags, etc in @prtm based on @rc data.
> > * rtm can be reallocated.
> > @@ -772,7 +834,6 @@ static int
> > update_rtm_from_rc(struct rt_addrinfo *info, struct rt_msghdr **prtm,
> > int alloc_len, struct rib_cmd_info *rc, struct nhop_object *nh)
> > {
> > - struct sockaddr_storage netmask_ss;
> > struct walkarg w;
> > union sockaddr_union saun;
> > struct rt_msghdr *rtm, *orig_rtm = NULL;
> > @@ -780,11 +841,14 @@ update_rtm_from_rc(struct rt_addrinfo *info, struct
> > rt
> > int error, len;
> >
> > rtm = *prtm;
> > + union sockaddr_union sa_dst, sa_mask;
> > + int family = info->rti_info[RTAX_DST]->sa_family;
> > + init_sockaddrs_family(family, &sa_dst.sa, &sa_mask.sa);
> > + export_rtaddrs(rc->rc_rt, &sa_dst.sa, &sa_mask.sa);
> >
> > - info->rti_info[RTAX_DST] = rt_key(rc->rc_rt);
> > + info->rti_info[RTAX_DST] = &sa_dst.sa;
> > + info->rti_info[RTAX_NETMASK] = rt_is_host(rc->rc_rt) ? NULL :
> > &sa_mask.sa;
> > info->rti_info[RTAX_GATEWAY] = &nh->gw_sa;
> > - info->rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rc->rc_rt),
> > - rt_mask(rc->rc_rt), &netmask_ss);
> > info->rti_info[RTAX_GENMASK] = 0;
> > ifp = nh->nh_ifp;
> > if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
> > @@ -994,7 +1058,9 @@ route_output(struct mbuf *m, struct socket *so, ...)
> > nh = rc.rc_nh_new;
> >
> > report:
> > - if (!can_export_rte(curthread->td_ucred, rc.rc_rt)) {
> > + if (!can_export_rte(curthread->td_ucred,
> > + info.rti_info[RTAX_NETMASK] == NULL,
> > + info.rti_info[RTAX_DST])) {
> > senderr(ESRCH);
> > }
> >
> > @@ -1730,35 +1796,34 @@ rt_dispatch(struct mbuf *m, sa_family_t saf)
> > *
> > * Returns 1 if it can, 0 otherwise.
> > */
> > -static int
> > -can_export_rte(struct ucred *td_ucred, const struct rtentry *rt)
> > +static bool
> > +can_export_rte(struct ucred *td_ucred, bool rt_is_host,
> > + const struct sockaddr *rt_dst)
> > {
> >
> > - if ((rt->rte_flags & RTF_HOST) == 0
> > - ? jailed_without_vnet(td_ucred)
> > - : prison_if(td_ucred, rt_key_const(rt)) != 0)
> > - return (0);
> > - return (1);
> > + if ((!rt_is_host) ? jailed_without_vnet(td_ucred)
> > + : prison_if(td_ucred, rt_dst) != 0)
> > + return (false);
> > + return (true);
> > }
> >
> > +
> > /*
> > * This is used in dumping the kernel table via sysctl().
> > */
> > static int
> > -sysctl_dumpentry(struct radix_node *rn, void *vw)
> > +sysctl_dumpentry(struct rtentry *rt, void *vw)
> > {
> > struct walkarg *w = vw;
> > - struct rtentry *rt = (struct rtentry *)rn;
> > struct nhop_object *nh;
> > int error = 0;
> >
> > NET_EPOCH_ASSERT();
> >
> > - 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))
> > + export_rtaddrs(rt, w->dst, w->mask);
> > + if (!can_export_rte(w->w_req->td->td_ucred, rt_is_host(rt), w->dst))
> > return (0);
> > - nh = rt->rt_nhop;
> > + nh = rt_get_raw_nhop(rt);
> > #ifdef ROUTE_MPATH
> > if (NH_IS_NHGRP(nh)) {
> > struct weightened_nhop *wn;
> > @@ -1783,13 +1848,17 @@ sysctl_dumpnhop(struct rtentry *rt, struct
> > nhop_object
> > {
> > struct rt_addrinfo info;
> > int error = 0, size;
> > - struct sockaddr_storage ss;
> > + uint32_t rtflags;
> >
> > + rtflags = nhop_get_rtflags(nh);
> > +
> > + if (w->w_op == NET_RT_FLAGS && !(rtflags & w->w_arg))
> > + return (0);
> > +
> > bzero((caddr_t)&info, sizeof(info));
> > - info.rti_info[RTAX_DST] = rt_key(rt);
> > + info.rti_info[RTAX_DST] = w->dst;
> > 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_NETMASK] = (rtflags & RTF_HOST) ? NULL : w->mask;
> > info.rti_info[RTAX_GENMASK] = 0;
> > if (nh->nh_ifp && !(nh->nh_ifp->if_flags & IFF_DYING)) {
> > info.rti_info[RTAX_IFP] = nh->nh_ifp->if_addr->ifa_addr;
> > @@ -1804,12 +1873,16 @@ sysctl_dumpnhop(struct rtentry *rt, struct
> > nhop_object
> >
> > bzero(&rtm->rtm_index,
> > sizeof(*rtm) - offsetof(struct rt_msghdr, rtm_index));
> > - if (rt->rte_flags & RTF_GWFLAG_COMPAT)
> > +
> > + /*
> > + * rte flags may consist of RTF_HOST (duplicated in nhop rtflags)
> > + * and RTF_UP (if entry is linked, which is always true here).
> > + * Given that, use nhop rtflags & add RTF_UP.
> > + */
> > + rtm->rtm_flags = rtflags | RTF_UP;
> > + if (rtm->rtm_flags & RTF_GWFLAG_COMPAT)
> > rtm->rtm_flags = RTF_GATEWAY |
> > - (rt->rte_flags & ~RTF_GWFLAG_COMPAT);
> > - else
> > - rtm->rtm_flags = rt->rte_flags;
> > - rtm->rtm_flags |= nhop_get_rtflags(nh);
> > + (rtm->rtm_flags & ~RTF_GWFLAG_COMPAT);
> > rt_getmetrics(rt, nh, &rtm->rtm_rmx);
> > rtm->rtm_rmx.rmx_weight = weight;
> > rtm->rtm_index = nh->nh_ifp->if_index;
> > @@ -2075,10 +2148,23 @@ sysctl_ifmalist(int af, struct walkarg *w)
> > return (error);
> > }
> >
> > +static void
> > +rtable_sysctl_dump(uint32_t fibnum, int family, struct walkarg *w)
> > +{
> > + union sockaddr_union sa_dst, sa_mask;
> > +
> > + w->family = family;
> > + w->dst = (struct sockaddr *)&sa_dst;
> > + w->mask = (struct sockaddr *)&sa_mask;
> > +
> > + init_sockaddrs_family(family, w->dst, w->mask);
> > +
> > + rib_walk(fibnum, family, false, sysctl_dumpentry, w);
> > +}
> > +
> > static int
> > sysctl_rtsock(SYSCTL_HANDLER_ARGS)
> > {
> > - RIB_RLOCK_TRACKER;
> > struct epoch_tracker et;
> > int *name = (int *)arg1;
> > u_int namelen = arg2;
> > @@ -2151,10 +2237,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
> > for (error = 0; error == 0 && i <= lim; i++) {
> > rnh = rt_tables_get_rnh(fib, i);
> > if (rnh != NULL) {
> > - RIB_RLOCK(rnh);
> > - error = rnh->rnh_walktree(&rnh->head,
> > - sysctl_dumpentry, &w);
> > - RIB_RUNLOCK(rnh);
> > + rtable_sysctl_dump(fib, i, &w);
> > } else if (af != 0)
> > error = EAFNOSUPPORT;
> > }
> > _______________________________________________
> > svn-src-all at freebsd.org mailing list
> > https://lists.freebsd.org/mailman/listinfo/svn-src-all
> > To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
> >
>
>
> --
> Mateusz Guzik <mjguzik gmail.com>
> _______________________________________________
> svn-src-all at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the svn-src-head
mailing list