On Tue, Jun 06, 2017 at 01:03:33PM +0200, Martin Pieuchot wrote:
> On 05/06/17(Mon) 16:52, Martin Pieuchot wrote:
> > On 05/06/17(Mon) 12:12, Martin Pieuchot wrote:
> > > Routing sockets are not protected by the NET_LOCK(). That's one of the
> > > boundaries of the network stack. That's whhy claudio@ sent some diffs
> > > to no longer require the KERNEL_LOCK() to protect them.
> > >
> > > But right now some rtm_* functions can be executed without
> > > KERNEL_LOCK(). That's wrong. Diff below fixes that and move the
> > > KERNEL_LOCK() further down in rtrequest(9) since the NET_LOCK() is
> > > enough to protect the other data structures.
> > >
> > > The scariest bits come from default router advertisements, but I guess
> > > that slaacd(8) saved us ;)
> >
> > Also change a KERNEL_ASSERT_LOCKED() into a NET_ASSERT_LOCK() in
> > rt_{set,put}gwroute(). Theses can now be called without KERNEL_LOCK()
> > when inserting an ARP entry.
>
> Hrvoje Popovski found the hard way that rtrequest(RTM_RESOLVE...) still
> need the KERNEL_LOCK() for malloc(9)/free(9).
>
> Here's a more conservative diff. ok?
>
Wondering why we don't push the lock into rtm_miss and rtm_send?
Apart from that I think we can start moving in that direction.
> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.357
> diff -u -p -r1.357 route.c
> --- net/route.c 27 May 2017 09:51:18 -0000 1.357
> +++ net/route.c 6 Jun 2017 11:01:05 -0000
> @@ -385,7 +385,7 @@ rt_setgwroute(struct rtentry *rt, u_int
> {
> struct rtentry *nhrt;
>
> - KERNEL_ASSERT_LOCKED();
> + NET_ASSERT_LOCKED();
>
> KASSERT(ISSET(rt->rt_flags, RTF_GATEWAY));
>
> @@ -442,7 +442,7 @@ rt_putgwroute(struct rtentry *rt)
> {
> struct rtentry *nhrt = rt->rt_gwroute;
>
> - KERNEL_ASSERT_LOCKED();
> + NET_ASSERT_LOCKED();
>
> if (!ISSET(rt->rt_flags, RTF_GATEWAY) || nhrt == NULL)
> return;
> @@ -624,7 +624,9 @@ out:
> info.rti_info[RTAX_DST] = dst;
> info.rti_info[RTAX_GATEWAY] = gateway;
> info.rti_info[RTAX_AUTHOR] = src;
> + KERNEL_LOCK();
> rtm_miss(RTM_REDIRECT, &info, flags, prio, ifidx, error, rdomain);
> + KERNEL_UNLOCK();
> }
>
> /*
> @@ -653,8 +655,10 @@ rtdeletemsg(struct rtentry *rt, struct i
> info.rti_flags = rt->rt_flags;
> ifidx = rt->rt_ifidx;
> error = rtrequest_delete(&info, rt->rt_priority, ifp, &rt, tableid);
> + KERNEL_LOCK();
> rtm_miss(RTM_DELETE, &info, info.rti_flags, rt->rt_priority, ifidx,
> error, tableid);
> + KERNEL_UNLOCK();
> if (error == 0)
> rtfree(rt);
> return (error);
> Index: netinet/in_pcb.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in_pcb.c,v
> retrieving revision 1.220
> diff -u -p -r1.220 in_pcb.c
> --- netinet/in_pcb.c 7 Mar 2017 16:59:40 -0000 1.220
> +++ netinet/in_pcb.c 6 Jun 2017 10:56:17 -0000
> @@ -716,8 +716,11 @@ in_losing(struct inpcb *inp)
> info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst;
> info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
> info.rti_info[RTAX_NETMASK] = rt_plen2mask(rt, &sa_mask);
> +
> + KERNEL_LOCK();
> rtm_miss(RTM_LOSING, &info, rt->rt_flags, rt->rt_priority,
> rt->rt_ifidx, 0, inp->inp_rtableid);
> + KERNEL_UNLOCK();
> if (rt->rt_flags & RTF_DYNAMIC)
> (void)rtrequest(RTM_DELETE, &info, rt->rt_priority,
> NULL, inp->inp_rtableid);
> Index: netinet6/nd6_rtr.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v
> retrieving revision 1.159
> diff -u -p -r1.159 nd6_rtr.c
> --- netinet6/nd6_rtr.c 30 May 2017 08:58:34 -0000 1.159
> +++ netinet6/nd6_rtr.c 6 Jun 2017 10:56:17 -0000
> @@ -613,7 +613,9 @@ defrouter_addreq(struct nd_defrouter *ne
> error = rtrequest(RTM_ADD, &info, RTP_DEFAULT, &rt,
> new->ifp->if_rdomain);
> if (error == 0) {
> + KERNEL_LOCK();
> rtm_send(rt, RTM_ADD, new->ifp->if_rdomain);
> + KERNEL_UNLOCK();
> rtfree(rt);
> new->installed = 1;
> }
> @@ -717,7 +719,9 @@ defrouter_delreq(struct nd_defrouter *dr
> error = rtrequest(RTM_DELETE, &info, RTP_DEFAULT, &rt,
> dr->ifp->if_rdomain);
> if (error == 0) {
> + KERNEL_LOCK();
> rtm_send(rt, RTM_DELETE, dr->ifp->if_rdomain);
> + KERNEL_UNLOCK();
> rtfree(rt);
> }
>
>
--
:wq Claudio