Let the kernel delete the (default) route when we deconfigure the
authorflorian <florian@openbsd.org>
Sat, 23 Jul 2022 09:33:18 +0000 (09:33 +0000)
committerflorian <florian@openbsd.org>
Sat, 23 Jul 2022 09:33:18 +0000 (09:33 +0000)
interface.

This works around a problem where the kernel always deletes
the first default route if there are multiple present
with the same gateway.

This only fixes the problem when running ifconfig inet -autoconf.

There are other cases where we call configure_rotures(RTM_DELETE), for
example when setting ignore routes in dhcpleased.conf and issuing a
reload. To fix that we either need help from the kernel to distinguish
routes by IFP or track priorities and hope they are unique.

Problem reported by mbuhl.
OK claudio

sbin/dhcpleased/dhcpleased.c

index bfd7c84..ef6200d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpleased.c,v 1.25 2022/07/23 09:29:20 florian Exp $ */
+/*     $OpenBSD: dhcpleased.c,v 1.26 2022/07/23 09:33:18 florian Exp $ */
 
 /*
  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -914,8 +914,22 @@ deconfigure_interface(struct imsg_configure_interface *imsg)
 
        memset(&ifaliasreq, 0, sizeof(ifaliasreq));
 
+#if 0
+       /*
+        * When two default routes have the same gateway the kernel always
+        * deletes the first which might be the wrong one. When we then
+        * deconfigure the IP address from the interface the kernel deletes
+        * all routes pointing out that interface and we end up with no
+        * default.
+        * This can happen with a wired & wireless interface on the same
+        * layer 2 network and the user issues ifconfig $WIFI inet -autoconf.
+        * Work around this issue by not deleting the default route and let
+        * the kernel handle it when we remove the IP address a few lines
+        * down.
+        */
        if (imsg->routes_len > 0)
                configure_routes(RTM_DELETE, imsg);
+#endif
 
        if (if_indextoname(imsg->if_index, ifaliasreq.ifra_name) == NULL) {
                log_warnx("%s: cannot find interface %d", __func__,