Hi bluhm,

On Fri, Jul 12, 2024 at 8:10 AM Alexander Bluhm <alexander.bl...@gmx.net> wrote:
>
> On Thu, Jul 11, 2024 at 09:51:33AM -0300, K R wrote:
> > >How-To-Repeat:
> >
> > On the server side:
> >
> > pass in quick inet6 proto udp to egress divert-to ::1 port 12345
> >
> > # nc -u -k -l ::1 12345
> >
> > On the client side:
> >
> > $ nc -u $server_ipv6 65000
> >
> > Anything typed in the client nc will appear on the server nc.  Typing
> > on the server nc won't show in the client one.  This incoming/outgoing
> > nc test works when using a TCP divert-to rule.
>
> divert to TCP is easy, UDP is complicated, nc is not smart enough
>
> My rule is
> pass in on vio1 proto { tcp udp } to port 12345 divert-to 127.0.0.1 port 1234
>
> When I tried it (with IPv4, but that does not matter) tcpdump showed:
> 12:51:42.844747 127.0.0.1.1234 > 10.188.234.17.39569: udp 3

Interesting, I've tried tcpdump and it didn't show localhost traffic
at all, on both vio0 and lo0.  I'm using vmd with bridge(4), will try
veb(4) to see if there is any difference.

> A packet with 127.0.0.1 must not apear on the wire, it will be
> dropped.
>
> nc does a connect(2) so the packet is sent to correct destination.
> But is still has its listen socket bound to 127.0.0.1.  So the
> packet source is wrong.
>
> A UDP server that wants to use divert-to correctly has to do this:
>
> - create socket
> - setsockopt IP_RECVDSTADDR
> - bind to 127.0.0.1
> - use recvmsg to get soure and destination address of packet
> - create new socket
> - bind and connect new socket to port and addresses received earlier
> - new socket can communicate bidirectional

It worked!  Just followed the steps above, using ::1 and
IPV6_RECVPKTINFO/IPV6_RECVDSTPORT for the IPv6 case.  The UDP server
can now reply back to the client using divert-to.

Thanks a lot!

Best,
--Kor

>
> With TCP the accept system call creates the new socket that is bound
> and connected correctly.  So it works out of the box.
>
> bluhm

Reply via email to