On 07/07/20(Tue) 01:01, Vitaliy Makkoveev wrote:
> On Mon, Jul 06, 2020 at 08:47:23PM +0200, Martin Pieuchot wrote:
> > On 06/07/20(Mon) 19:23, Vitaliy Makkoveev wrote:
> > > > On 6 Jul 2020, at 17:36, Martin Pieuchot <[email protected]> wrote:
> > > [...] 
> > > Unfortunately you can’t be sure about NET_LOCK() status while you are
> > > in pppac_start(). It was described at this thread [1].
> > > 
> > > We have two cases:
> > > 1. pppac_start() called from pppac_output(). NET_LOCK() was inherited.
> > 
> > Such recursions should be avoided.  if_enqueue() should take care of
> > that.
> 
> I suggest to finish the route to if_get(9) before. Updated diff which
> removes pipexintr() below. Just against the most resent source tree.

The tasks are not orthogonal.  Making sure the NET_LOCK() is taken
inside the pipex boundaries help for this task as well.

That said the current code is not ready for the proposed diff.  At
least `pppx_devs', `pipex_rd_head4' and `pipex_rd_head6' must be
protected/annotated. 

What about all the lists/hashtables?  They aren't annotated, are they
all protected by the NET_LOCK()?

What about `pppx_ifs' is it only used under the KERNEL_LOCK()?

One comment below:

> Index: sys/net/pipex.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pipex.c,v
> retrieving revision 1.119
> diff -u -p -r1.119 pipex.c
> --- sys/net/pipex.c   6 Jul 2020 20:37:51 -0000       1.119
> +++ sys/net/pipex.c   6 Jul 2020 21:55:17 -0000
> @@ -948,8 +861,26 @@ pipex_ip_output(struct mbuf *m0, struct 
>               m0->m_flags &= ~(M_BCAST|M_MCAST);
>  
>       /* output ip packets to the session tunnel */
> -     if (pipex_ppp_enqueue(m0, session, &pipexoutq))
> -             goto dropped;
> +     if (session->is_multicast != 0) {
> +             struct pipex_session *session_tmp;
> +             struct mbuf *m;
> +

Please add a NET_ASSERT_LOCKED() here to indicate that `pipex_session_list'
needs it.

> +             LIST_FOREACH(session_tmp, &pipex_session_list, session_list) {
> +                     if (session->pipex_iface != session_tmp->pipex_iface)
> +                             continue;
> +                     if (session_tmp->ip_forward == 0 &&
> +                         session_tmp->ip6_forward == 0)
> +                             continue;
> +                     m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
> +                     if (m == NULL) {
> +                             session->stat.oerrors++;
> +                             continue;
> +                     }
> +                     pipex_ppp_output(m, session_tmp, PPP_IP);
> +             }
> +             m_freem(m);
> +     } else
> +             pipex_ppp_output(m0, session, PPP_IP);
>  
>       return;
>  drop:

Reply via email to