From 5a55e5184647d9b03e8d34dccd7a4e1613508cac Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 23 Jul 2022 09:29:20 +0000 Subject: [PATCH] Send an IFP to distinguish (default) routes over different interfaces to the same gateway. Unfortunately this doesn't help with deleting the correct route when issuing ifconfig inet -autoconf, the kernel always deletes the first route. This is the one with the lowest priority if the routes have different priorities. What does work is identifying routes by priority but dhcpleased(8) doesn't set the priority so that the kernel choses the right one when adding a route and it doesn't yet track the priority the kernel set. Another issue is that we might end up with routes having the same gateway and same priority pointing out of different interfaces. For example when two ethernet interfaces are set to autoconf and they are connected to the layer 2 network. This seems like a bad idea but it is something that could be configured. Problem reported by mbuhl, claudio suggested to try to send an IFP. Even though it doesn't work, it seems worthwhile to send the IFP for when the kernel gains the ability to distinguish routes by IFP. --- sbin/dhcpleased/dhcpleased.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sbin/dhcpleased/dhcpleased.c b/sbin/dhcpleased/dhcpleased.c index f57dda59a4f..bfd7c84e6e0 100644 --- a/sbin/dhcpleased/dhcpleased.c +++ b/sbin/dhcpleased/dhcpleased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpleased.c,v 1.24 2022/03/21 04:35:41 dlg Exp $ */ +/* $OpenBSD: dhcpleased.c,v 1.25 2022/07/23 09:29:20 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -1014,8 +1015,9 @@ configure_route(uint8_t rtm_type, uint32_t if_index, int rdomain, struct struct sockaddr_in *ifa, int rtm_flags) { struct rt_msghdr rtm; + struct sockaddr_dl ifp; struct sockaddr_rtlabel rl; - struct iovec iov[12]; + struct iovec iov[14]; long pad = 0; int iovcnt = 0, padlen; @@ -1028,7 +1030,8 @@ configure_route(uint8_t rtm_type, uint32_t if_index, int rdomain, struct rtm.rtm_tableid = rdomain; rtm.rtm_seq = ++rtm_seq; rtm.rtm_priority = RTP_NONE; - rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_LABEL; + rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP | + RTA_LABEL; rtm.rtm_flags = RTF_UP | RTF_STATIC | RTF_MPATH | rtm_flags; if (ifa) @@ -1067,6 +1070,20 @@ configure_route(uint8_t rtm_type, uint32_t if_index, int rdomain, struct rtm.rtm_msglen += padlen; } + memset(&ifp, 0, sizeof(ifp)); + ifp.sdl_len = sizeof(struct sockaddr_dl); + ifp.sdl_family = AF_LINK; + ifp.sdl_index = if_index; + iov[iovcnt].iov_base = &ifp; + iov[iovcnt++].iov_len = sizeof(ifp); + rtm.rtm_msglen += sizeof(ifp); + padlen = ROUNDUP(sizeof(ifp)) - sizeof(ifp); + if (padlen > 0) { + iov[iovcnt].iov_base = &pad; + iov[iovcnt++].iov_len = padlen; + rtm.rtm_msglen += padlen; + } + if (ifa) { iov[iovcnt].iov_base = ifa; iov[iovcnt++].iov_len = ifa->sin_len; -- 2.20.1