Currently when a umb device gets a new IPv4 address, it just adds it to
the interface and tries to set the default route through it.  If there's
a different previous address, it stays there, and any routes using it also
remain in place, so umb can't set the new default route.  You see something
like this:

  umb0: unable to set IPv4 default route, error 17

and then you no longer have a working default route.

The diff below removes the old address before setting the new one.
SIOCDIFADDR with no details in the request will delete whatever v4 address
exists on the interface, and consequently remove routes, so umb will then be
able to add the new interface and set the new default route.

With this diff, I've had an ssh session inside a wg tunnel survive across 5
address changes on the umb interface that carries the wireguard traffic.
Without, wireguard stops working after the first address change and my ssh
session goes with it.

ok?

Index: if_umb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_umb.c,v
retrieving revision 1.55
diff -u -p -r1.55 if_umb.c
--- if_umb.c    1 Sep 2023 20:24:29 -0000       1.55
+++ if_umb.c    11 Oct 2023 23:18:50 -0000
@@ -1815,6 +1815,14 @@ umb_add_inet_config(struct umb_softc *sc
        int      rv;
 
        memset(&ifra, 0, sizeof (ifra));
+       rv = in_ioctl(SIOCDIFADDR, (caddr_t)&ifra, ifp, 1);
+       if (rv != 0 && rv != EADDRNOTAVAIL) {
+               printf("%s: unable to delete IPv4 address, error %d\n",
+                   DEVNAM(ifp->if_softc), rv);
+               return rv;
+       }
+
+       memset(&ifra, 0, sizeof (ifra));
        sin = &ifra.ifra_addr;
        sin->sin_family = AF_INET;
        sin->sin_len = sizeof (*sin);

Reply via email to