On 11/11/15(Wed) 13:00, Martin Pieuchot wrote:
> Mostly around rtrequest(9) code, ok?
Anybody?
> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.270
> diff -u -p -r1.270 route.c
> --- net/route.c 11 Nov 2015 11:25:16 -0000 1.270
> +++ net/route.c 11 Nov 2015 11:40:55 -0000
> @@ -806,6 +806,7 @@ int
> rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
> struct rtentry **ret_nrt, u_int tableid)
> {
> + struct ifnet *ifp;
> struct rtentry *rt, *crt;
> struct ifaddr *ifa;
> struct sockaddr *ndst;
> @@ -870,7 +871,12 @@ rtrequest(int req, struct rt_addrinfo *i
> rt->rt_parent = NULL;
>
> rt->rt_flags &= ~RTF_UP;
> - rt->rt_ifp->if_rtrequest(rt->rt_ifp, RTM_DELETE, rt);
> +
> + ifp = if_get(rt->rt_ifidx);
> + KASSERT(ifp != NULL);
> + ifp->if_rtrequest(ifp, RTM_DELETE, rt);
> + if_put(ifp);
> +
> atomic_inc_int(&rttrash);
>
> if (ret_nrt != NULL)
> @@ -911,8 +917,9 @@ rtrequest(int req, struct rt_addrinfo *i
> if (info->rti_ifa == NULL && (error = rt_getifa(info, tableid)))
> return (error);
> ifa = info->rti_ifa;
> + ifp = ifa->ifa_ifp;
> if (prio == 0)
> - prio = ifa->ifa_ifp->if_priority + RTP_STATIC;
> + prio = ifp->if_priority + RTP_STATIC;
>
> dlen = info->rti_info[RTAX_DST]->sa_len;
> ndst = malloc(dlen, M_RTABLE, M_NOWAIT);
> @@ -941,8 +948,8 @@ rtrequest(int req, struct rt_addrinfo *i
> /* Check the link state if the table supports it. */
> if (rtable_mpath_capable(tableid, ndst->sa_family) &&
> !ISSET(rt->rt_flags, RTF_LOCAL) &&
> - (!LINK_STATE_IS_UP(ifa->ifa_ifp->if_link_state) ||
> - !ISSET(ifa->ifa_ifp->if_flags, IFF_UP))) {
> + (!LINK_STATE_IS_UP(ifp->if_link_state) ||
> + !ISSET(ifp->if_flags, IFF_UP))) {
> rt->rt_flags &= ~RTF_UP;
> rt->rt_priority |= RTP_DOWN;
> }
> @@ -989,7 +996,7 @@ rtrequest(int req, struct rt_addrinfo *i
>
> ifa->ifa_refcnt++;
> rt->rt_ifa = ifa;
> - rt->rt_ifp = ifa->ifa_ifp;
> + rt->rt_ifp = ifp;
> if (rt->rt_flags & RTF_CLONED) {
> /*
> * If the ifa of the cloning route was stale, a
> @@ -998,16 +1005,21 @@ rtrequest(int req, struct rt_addrinfo *i
> * route.
> */
> if ((*ret_nrt)->rt_ifa->ifa_ifp == NULL) {
> - printf("rtrequest RTM_RESOLVE: wrong ifa (%p) "
> - "was (%p)\n", ifa, (*ret_nrt)->rt_ifa);
> - (*ret_nrt)->rt_ifp->if_rtrequest(rt->rt_ifp,
> - RTM_DELETE, *ret_nrt);
> + struct ifnet *ifp0;
> +
> + printf("%s RTM_RESOLVE: wrong ifa (%p) was (%p)"
> + "\n", __func__, ifa, (*ret_nrt)->rt_ifa);
> +
> + ifp0 = if_get((*ret_nrt)->rt_ifidx);
> + KASSERT(ifp0 != NULL);
> + ifp0->if_rtrequest(ifp0, RTM_DELETE, *ret_nrt);
> ifafree((*ret_nrt)->rt_ifa);
> - (*ret_nrt)->rt_ifa = ifa;
> - (*ret_nrt)->rt_ifp = ifa->ifa_ifp;
> + if_put(ifp0);
> +
> ifa->ifa_refcnt++;
> - (*ret_nrt)->rt_ifp->if_rtrequest(rt->rt_ifp,
> - RTM_ADD, *ret_nrt);
> + (*ret_nrt)->rt_ifa = ifa;
> + (*ret_nrt)->rt_ifp = ifp;
> + ifp->if_rtrequest(ifp, RTM_ADD, *ret_nrt);
> }
> /*
> * Copy both metrics and a back pointer to the cloned
> @@ -1056,7 +1068,7 @@ rtrequest(int req, struct rt_addrinfo *i
> pool_put(&rtentry_pool, rt);
> return (EEXIST);
> }
> - rt->rt_ifp->if_rtrequest(rt->rt_ifp, req, rt);
> + ifp->if_rtrequest(ifp, req, rt);
>
> if ((rt->rt_flags & RTF_CLONING) != 0) {
> /* clean up any cloned children */
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.182
> diff -u -p -r1.182 rtsock.c
> --- net/rtsock.c 9 Nov 2015 10:26:26 -0000 1.182
> +++ net/rtsock.c 11 Nov 2015 11:58:35 -0000
> @@ -750,15 +750,18 @@ report:
> goto flush;
> if (ifa) {
> if (rt->rt_ifa != ifa) {
> - rt->rt_ifp->if_rtrequest(
> - rt->rt_ifp, RTM_DELETE, rt);
> + ifp = if_get(rt->rt_ifidx);
> + KASSERT(ifp != NULL);
> + ifp->if_rtrequest(ifp, RTM_DELETE, rt);
> ifafree(rt->rt_ifa);
> - rt->rt_ifa = ifa;
> + if_put(ifp);
> +
> ifa->ifa_refcnt++;
> + rt->rt_ifa = ifa;
> rt->rt_ifp = ifa->ifa_ifp;
> #ifndef SMALL_KERNEL
> /* recheck link state after ifp change*/
> - rt_if_linkstate_change(rt, rt->rt_ifp,
> + rt_if_linkstate_change(rt, ifa->ifa_ifp,
> tableid);
> #endif
> }
> @@ -815,13 +818,17 @@ report:
> rtm->rtm_index = rt->rt_ifidx;
> rtm->rtm_priority = rt->rt_priority & RTP_MASK;
> rtm->rtm_flags = rt->rt_flags;
> - rt->rt_ifp->if_rtrequest(rt->rt_ifp, RTM_ADD, rt);
> +
> + ifp = if_get(rt->rt_ifidx);
> + KASSERT(ifp != NULL);
> + ifp->if_rtrequest(ifp, RTM_ADD, rt);
> + if_put(ifp);
> +
> if (info.rti_info[RTAX_LABEL] != NULL) {
> char *rtlabel = ((struct sockaddr_rtlabel *)
> info.rti_info[RTAX_LABEL])->sr_label;
> rtlabel_unref(rt->rt_labelid);
> - rt->rt_labelid =
> - rtlabel_name2id(rtlabel);
> + rt->rt_labelid = rtlabel_name2id(rtlabel);
> }
> if_group_routechange(info.rti_info[RTAX_DST],
> info.rti_info[RTAX_NETMASK]);
>