On Fri, Nov 09, 2018 at 06:57:16PM +0100, Claudio Jeker wrote:
> On Fri, Nov 09, 2018 at 06:09:34PM +0100, Jan Klemkow wrote:
> > I printed the code path below to make it easier to review the diff.
> > While I was following the code path again, I found an inconsistency
> > between udp_output() and upd6_output().  Just upd_output() turns EACCES
> > to EHOSTUNREACH, udp6_output does not.  The Diff below fixes udp6_output
> > and rounds up the sendto(2) manpage.
> > 
> > Reviewer guide from sendto(2) to EHOSTUNREACH:
> > 
> > sys_sendto() -> sendit() -> sosend() ---+
> >                                     |
> >  +--------------------------------------+
> >  |
> >  +-> udp_usrreq() -> udp_output():
> >  |  ...
> >  |  error = ip_output(m, inp->inp_options, &inp->inp_route,
> >  |      (inp->inp_socket->so_options & SO_BROADCAST), inp->inp_moptions,
> >  |      inp, ipsecflowinfo);
> >  |  if (error == EACCES)    /* translate pf(4) error for userland */
> >  |          error = EHOSTUNREACH;
> >  |  ...
> >  |
> >  +-> udp_usrreq() -> udp6_output():
> >  |  ...
> >  |  error = ip6_output(m, optp, &in6p->inp_route6,
> >  |      flags, in6p->inp_moptions6, in6p);
> >  |  if (error == EACCES)    /* translate pf(4) error for userland */
> >  |          error = EHOSTUNREACH;
> >  |  ...
> >  |
> >  +-> tcp_usrreq() -> tcp_output():
> >     ...
> >     error = ip_output(m, tp->t_inpcb->inp_options,
> >             tp->t_inpcb->inp_route,
> >             ip_mtudisc ? IP_MTUDISC : 0), NULL, tp->t_inpcb, 0);
> >     ...
> >     error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
> >             &tp->t_inpcb->inp_route6,
> >             0, NULL, tp->t_inpcb);
> >     ...
> >     if (error == EACCES)    /* translate pf(4) error for userland */
> >             error = EHOSTUNREACH;
> >     ...
> > 
> 
> I really don't like this translation and therefor change of semantics of
> an old documented errno code.
> 
> If I remember correctly this was added because of the fear that EACCES was
> not properly handled when used with write(2) since it is not documented
> there but neither is EHOSTUNREACH.
> 
> I would prefer to remove this errno translation magic for pf(4) in the
> midlayer of the network code. As shown it is always prone for errors.

Hi Claudio,

Perfect, I also think its more intuitive to get a "permission denied"
in case of a pf(4) block then a "Host is unreachable".  The diff below
corrects kernel and extents the manpage for pf(4) blocks.

Thanks,
Jan

Index: sys/netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.127
diff -u -p -r1.127 tcp_output.c
--- sys/netinet/tcp_output.c    9 Nov 2018 14:14:31 -0000       1.127
+++ sys/netinet/tcp_output.c    9 Nov 2018 18:53:02 -0000
@@ -1084,8 +1084,6 @@ out:
                        tcp_mtudisc(tp->t_inpcb, -1);
                        return (0);
                }
-               if (error == EACCES)    /* translate pf(4) error for userland */
-                       error = EHOSTUNREACH;
                if ((error == EHOSTUNREACH || error == ENETDOWN) &&
                    TCPS_HAVERCVDSYN(tp->t_state)) {
                        tp->t_softerror = error;
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.253
diff -u -p -r1.253 udp_usrreq.c
--- sys/netinet/udp_usrreq.c    4 Oct 2018 17:33:41 -0000       1.253
+++ sys/netinet/udp_usrreq.c    9 Nov 2018 18:52:08 -0000
@@ -1004,8 +1004,6 @@ udp_output(struct inpcb *inp, struct mbu
        error = ip_output(m, inp->inp_options, &inp->inp_route,
            (inp->inp_socket->so_options & SO_BROADCAST), inp->inp_moptions,
            inp, ipsecflowinfo);
-       if (error == EACCES)    /* translate pf(4) error for userland */
-               error = EHOSTUNREACH;
 
 bail:
        m_freem(control);
Index: lib/libc/sys//send.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/send.2,v
retrieving revision 1.32
diff -u -p -r1.32 send.2
--- lib/libc/sys//send.2        5 Oct 2017 12:30:16 -0000       1.32
+++ lib/libc/sys//send.2        9 Nov 2018 19:06:47 -0000
@@ -162,7 +162,9 @@ The output queue for a network interface
 This generally indicates that the interface has stopped sending,
 but may be caused by transient congestion.
 .It Bq Er EACCES
-The
+The connection was blocked by
+.Xr pf 4 ,
+or
 .Dv SO_BROADCAST
 option is not set on the socket, and a broadcast address
 was given as the destination.

Reply via email to