Hello, thanks for the comment.

On 3/27/22 18:25, YASUOKA Masahiko wrote:
Hi,

On Wed, 9 Mar 2022 15:28:44 +0900
Yuichiro NAITO <naito.yuich...@gmail.com> wrote:
I see 'Address already in use' message,
when I change wgrtable for a running wg interface.
It doesn't make sense to me.

It can be reproduced by the following command sequence.

```
# route -T1 add default `cat /etc/mygate`
# ifconfig wg0 create wgport 7111 wgkey `cat /etc/mykey.wg0`
# ifconfig wg0 up
# ifconfig wg0 wgrtable 1
ifconfig: SIOCSWG: Address already in use
```

When I down wg0 interface before changing wgrtable,
It succeeds and no messages are shown.

I investigated the reason why 'Address already in use' is shown.

If wgrtable is specified by ifconfig argument,
`wg_ioctl_set` function in `sys/net/if_wg.c` is called.

And if the wg interface is running, `wg_bind` function is called.
`wg_bind` creates new sockets (IPv4 and 6) and replace them from old
ones.

If only wgrtable is changed, `wg_bind` binds as same port as existing
sockets.
So 'Address already in use' is shown.

Here is a simple patch to close existing sockets before `wg_bind`.
It works for me but I'm not 100% sure this is right fix.

Any other ideas?

```
diff --git a/sys/net/if_wg.c b/sys/net/if_wg.c
index 4dae3e3c976..0159664fb34 100644
--- a/sys/net/if_wg.c
+++ b/sys/net/if_wg.c
@@ -2253,11 +2253,14 @@ wg_ioctl_set(struct wg_softc *sc, struct
wg_data_io *data)
        if (port != sc->sc_udp_port || rtable != sc->sc_udp_rtable) {
                TAILQ_FOREACH(peer, &sc->sc_peer_seq, p_seq_entry)
                        wg_peer_clear_src(peer);

-               if (sc->sc_if.if_flags & IFF_RUNNING)
+               if (sc->sc_if.if_flags & IFF_RUNNING) {
+                       if (port == sc->sc_udp_port)
+                               wg_unbind(sc);
                        if ((ret = wg_bind(sc, &port, &rtable)) != 0)
                                goto error;
+               }

                sc->sc_udp_port = port;
                sc->sc_udp_rtable = rtable;
        }
```

If rdomain 1 exists, the error will not shown.

  # ifconfig vether0 rdomain 1 up
  # ifconfig wg0 create wgport 7111 wgkey `openssl rand -base64 32` up
  # ifconfig wg0 wgrtable 1
  #

Yes, if rdomain 1 is created before `ifconfig wg0 wgrtable 1`,
setting wgrtable succeeds and there is no problem.

In the case which you reported to, it is supposed that rtable 1 exists
but rdomain 1 doesn't exist.

Even when "wgtable 1" is configured, becase there is no dedicated
rdomain, rdomain 0 will be used to bind the UDP port.

Exactly, it's the case that I reported and want to fix.

So what wg(4) should do for this case is "nothing".

I'm a little bit confused.
As you said, I can confirm your patch doesn't set wgrtable in my use case.
It is not the result that I wanted.

So the diff is updated.

ok?

Index: sys/net/if_wg.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/net/if_wg.c,v
retrieving revision 1.22
diff -u -p -r1.22 if_wg.c
--- sys/net/if_wg.c     22 Feb 2022 01:15:02 -0000      1.22
+++ sys/net/if_wg.c     27 Mar 2022 09:17:08 -0000
@@ -2250,7 +2250,8 @@ wg_ioctl_set(struct wg_softc *sc, struct
        else
                rtable = sc->sc_udp_rtable;
- if (port != sc->sc_udp_port || rtable != sc->sc_udp_rtable) {
+       if (port != sc->sc_udp_port ||
+           rtable_l2(rtable) != sc->sc_udp_rtable) {
                TAILQ_FOREACH(peer, &sc->sc_peer_seq, p_seq_entry)
                        wg_peer_clear_src(peer);

--
Yuichiro NAITO (naito.yuich...@gmail.com)

Reply via email to